Re: [Vala] Scoping error in public constant members



Oops, I accidentally sent it without finishing my train of thought...

The c file would need to have a pointer declared in global scope.  It would probably be better to use GObject * rather than void * as well.

The question is - how to make sure the initializer function is called in C.

Automatic initialization is problematic.  Java gets around it by having run time verification of each class file, initializing each static final object it finds.  I imagine C# does something similar in the CLI backend.   So how could we do it in C....

Maybe something like this could work - just speculation....

The compiler could create a single function per namespace that could be called whenever the using keyword is used, it would need to chain to all other namespaces_init functions used by classes in that namespace.

So if our vala code looked like this:

using GLib;
using SomeNamespace;

namespace ConstNameSpace {

      class ConstantHolder {

           const SomeObject = new SomeObject();

     .....
     }

     static int main(string args[]) {

            val somevalue = ConstantHolder.SomeObject.getvalue();

     }
}

so the resulting C code could look like this:

.h:

extern GObject * CONST_NAME_SPACE_CONSTANT_HOLDER_SOME_OBJECT;

.c:

GObject * CONST_NAME_SPACE_CONSTANT_HOLDER_SOME_OBJECT;

void CONST_NAME_SPACE_constant_initializer(void) {

          static int initialized = 0;
          if(initialized ==0) {

                GLIB_constant_initializer();
                Some_Namespace_constant_initializer();

               CONST_NAME_SPACE_CONSTANT_HOLDER_SOME_OBJECT =               CONST_NAME_SPACE_CONSTANT_HOLDER_SOME_OBJECT_contruct();

               initialized = 1;
          }

}

void main(int argc, char **argv) {

        CONST_NAME_SPACE_constant_initializer();
        .....

}

This would handle chaining the initializers inside a namespace.  As shown the resulting main function would also have to call the initializer for it's name space.

The drawback to this, is that you would need to compile all the vala files for a namespace at once to make sure the initializer function was up to date. 

Just some thoughts....

Cayle












At this point, I'm not sure what advantage a const object would have over a public static object other than allowing the compiler to check for and disallow modification, but the same issues hold for public static objects contained in a class (just not declared const), i.e how do you create the C file so that those static objects can be accessible from files other than the file they are created in.



 


On 9/1/06, Cayle Graumann <cayle graumann gmail com> wrote:
Jurg,

     I agree that having the static const and #define are equivalent with optimizing compilers for fundamental datatypes, and I'd much rather have static const than the #define.  An optimizing compiler should be almost efficient at optimizing calls to extern const data as well though.   I had forgotten about not being able to call functions in initilizers in C -- for some reason I was thinking that had been relaxed in the C99 standard, but after looking at the spec (google is my friend) I see that has not changed.  If we had const pointers to objects, I guess we would have to call an initializer or constructor function before they could be used. 

Something like this:

vala:

namespace Test {
class Constant_Holder  {

        const  BigObject = new BigObject()

}   
}



This would have to turn into something like :

h: 

extern const void * CONSTANT_HOLDER_BIGOBJECT;

c:

void CONSTANT_HOLDER_init() {
          static int initialized = 0;
         if(initialized == 0) {

                 CONSTANT_HOLDER_BIGOBJECT = BIGOBJECT_construct();
                 initialized = 1;

        }
}




On 9/1/06, Jürg Billeter < j bitron ch> wrote:
Hi Cayle,

On Don, 2006-08-31 at 16:17 -0500, Cayle Graumann wrote:
>      You are thinking of something like this?
>
> h file:
>
> static const int CONSTANT_HOLDER_X = 20;

Just that static const in the header.

> The static const int will give you a copy in every file that calls the
> header, but the scope will be limited to that object file, and so will

I'd expect that the compiler will be able to optimize the static const
away - unless you use &CONSTANT_HOLDER_X in your sources.

>  compile.  The #define method would be the most memory efficient ( you
> wouldn't even need the declaration in the c file as a static int, as
> it could be a define as well), because the preprocessor would replace
> every instance of CONSTANT_HOLDER_X with the value 20.  Now this would
> definitely work with fundamental datatypes, but I don't know if it
> would work for structs and pointers;

#define and static const should be nearly the same in an optimizing
compiler except that consts are typed and work with structs.

>
> I was thinking more on the lines of this:
>
> c file:
> const int CONSTANT_HOLDER_X = 20;
>
> h file:
> extern const int CONSTANT_HOLDER_X;
>
> This would get you only one memory allocation in the object file where
> the class is defined, and the compiler would optimize all calls in
> other compilation modules to point to that memory location.  This

That's right but #define and static const normally don't need any
runtime memory at all and the compiler can do things like constant
folding.

>  should work for object pointers as well as structs, as then the
> declaration would be
>
> c file:
> const GObject * CONSTANT_HOLDER_OBJECT = ......
>
> h file:
> extern const GObject * CONSTANT_HOLDER_OBJECT;
>
> The pointer is constant, not the value the pointer points to, and the
> compiler should know what to do from there.

How would you initialize the pointer constant, i.e. where do you get the
object pointer from? You can't call functions in initializers in C, as
far as I know...

> The trickiness about all this comes because we are compiling to C and
> not to machine code and so are inherently limited to the C scope
> limitations.  It would be nice to know how the early C++ compilers
> ( which were really C preprocessors) also handled some of these
> issues.

It's a lot less trickier than writing our own optimized assembler code.
A GCC frontend might be nice one day but it comes with its own problems.

Jürg





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]