#1
  1. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    8
    Rep Power
    0

    link problem with static member variable


    I have declared a static member variable inside a class, and I want this variable to be accessible by other classes inside the project.

    This is my first use of DevSHed so bear with me if the formatting doesn't come out correctly...

    In file Master.h, I have:
    PHP Code:
    class Master {

    public :
        static 
    void    DetermineEndian();
        static    
    int    endianByteOrder;
    }; 
    In file Master.cpp, I have:

    PHP Code:
    void Master::DetermineEndian() {

        
    union {
            
    long l;
            
    char c[4];
        } 
    test;

        
    test.1;

        if (
    test.c[3] == && (test.c[2] == test.c[1] == test.c[0] == 0) )
            
    endianByteOrder BYTE_ORDER_BIG_ENDIAN;
        else if (
    test.c[3] == && (test.c[2] == test.c[1] == test.c[0] == 1) )
            
    endianByteOrder =    BYTE_ORDER_LITTLE_ENDIAN;
        else 
    endianByteOrder =BYTE_ORDER_UNKNOWN;
        
    return;    

    In Microsoft Visual C++ .Net, I get the following error.

    Master error LNK2001: unresolved external symbol "public: static int Master::endianByteOrder" (?endianByteOrder@Master@@2HA)

    This really doesn't seem right. I know it's been a while since I've done C++, but it seems to be that I should be able to modify a static member variable within a static member function.

    I have included Master.h in this file, and have ifdefs around Master.h to keep it from being read repeatedly, as it is also used by other files (every other main header calls this one).

    Any suggestions?
    Last edited by En Sabah Nur; August 7th, 2003 at 04:14 AM.
  2. #2
  3. Left due to despotic ad-min
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2003
    Posts
    1,044
    Rep Power
    13
    Add the declaration

    int Master::endianByteOrder

    at file scope (i.e. outside a function) in Master.cpp.

    All the declaration in the class does is tell the compiler there is
    an int that is shared between all instances of the class. The declaration above is needed to make the int exist somewhere.

    Similar thing to declaring a variable extern in a header file; it is necessary to also declare it without the extern qualifier in one (and only one) source file.
  4. #3
  5. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    8
    Rep Power
    0
    I appreciate the help there. Now I remember having to do that with C, and I should have tried it this as well.

    Just seems kind of odd though. Why do I have to do it with this member variable, and I don't for member variables of other classes? Or do I? I could just be forgetting, but I don't remember having to do this with static member variables in the past. It's been a while since I've done C++, but I did Java recently and can't remember this being a necessity.

    Anyway, thanks alot!!! It's working now...
  6. #4
  7. Left due to despotic ad-min
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2003
    Posts
    1,044
    Rep Power
    13
    The reason this trick is necessary for static members of C++ classes (or for static variables in C) is the fact that we tend to have dumb linkers. In theory, it is possible to do away with needing to explicitly declare static variables, but that theory relies on having a smart linker (eg one that can look at multiple object files that all declare a static, work out they all need to refer to exactly one value, and assign that value for them to refer to).

    The C and C++ standard basically require that statics are explicitly allocated at most once. If you don't allocate a static at all then, in practice, you run foul of dumb linkers. If you allocate a static only once, then dumb linkers are happy and smart linkers will effectively ignore the declaration. If you allocate a static more than once (eg in multiple source files) the standards explicitly state that you invoke undefined behaviour --- i.e. you shouldn't do it.

    The reason it is not necessary in Java is that Java has a simpler compile and link model (eg everything is forced to be declared in a class). That's a trade-off; while the handling of static variables is simpler and cleaner for the Java programmer, some things that are easier in C or C++ because of the way those languages allow handling compilation and linkage of multiple files.

IMN logo majestic logo threadwatch logo seochat tools logo