开发者

changes to static variable goes out of scope? (C++)

I have a header file containing static variables, such as window width and height.

I read new values for these variables through a XML file, but these changes does not seem to be registered once the function it was changed in, goes out of scope.

Example to illustrate:

// These are in a separate h开发者_C百科eader file  
static int width = 0;  
static int height = 0;  

aClass::Init()  
{  
    width = readFromXMLFile(); // returning 800  
    height = readFromXMLFile(); // returning 600  

    // Here width and height are 800/600
}

aClass::Run()  
{  
    ...  
}  

Main  
{  
    Init()  
    // Here, width and height are 0/0 again  
    Run()
}  


Wait a minute ... you have

static int height = 0;
static int width = 0;

in a header file? That will create file-scoped statics in each compilation unit that includes the header. If you want to use global variables, then declare them as extern in the header and define them in one compilation unit.


If you don't declare a static as extern somewhere, what you'll end up with are actually multiple copies of statics (by the same name) per compilation unit.

Correct example:

test.h

extern int mystatic;

test.cpp

int mystatic = 0;

void myFunction() // or member funciton, who cares
{
    mystatic = 42;
}

main.cpp

#include "test.h"

int main()
{
     std::cout << mystatic << std::endl; // prints 0
     // 
     myFunction(); // or use classes and trigger the same

     // 
     std::cout << mystatic << std::endl; // prints 42
     return 0;
 }

HTH


You should declare your static variables in a header file, externed and define them in a cpp file.

.h file:

extern int foo;

.cpp file somewhere:

int foo;


I think you are misunderstanding the the keyword static. In C++ this keyword has many meanings, all loosely related.

At the top level, not inside a class, struct or function definition, the keyword static creates a weird sort of global variable. That global variable is only visible in the 'compilation unit' in which it appears. The idea of a 'compilation unit' is created by the way the C++ preprocessor works.

All of the stuff starting with # are not part of the C++ language proper, but part of the preprocessor. The preprocessor reads all those directives and pieces together a compilation unit. It expands all of the macros, and replaces all the #include directives with the contents of the file mentioned in the directive.

With gcc, you can see the result of this by passing the -E option to the compiler. That will show you the contents of the resulting 'compilation unit' when you compile a C++ file.

You will notice that all of the #includeed header files become part of the compilation unit.

Now, on to file-level static variables...

These variables are local to a compilation unit. If you declare file level static variables with the same name in another compilation unit, they will be different variables. If you alter the values in one compilation unit, they have no relation to the values of these variables in the other compilation units.

Remember how header files end up basically being copied into each compilation unit?

That means that file level static variables declared in header files end up having copies in each compilation unit. They will be seemingly global, but in fact will have many non-interacting copies.

In your case, you can easily solve this problem by making them fully global variables. You can do this using the extern keyword in the header file. This basically puts the compiler on notice that global variables exist with that name. Then you declare them as non-extern in one particular compilation unit. The variables then are given space in the .o file that results from compiling that compilation unit. So basically:

In foo.h:

extern int width;
extern int height;

In some_random.cpp (but probably foo.cpp):

#include "foo.h"

int width = 0;
int height = 0;

The concept of a compilation unit is only relevant for file-level (not inside a class, struct or function definition) static variables. Static variables declared inside class, struct or function definitions obey some different rules. Somehow, once you understand each of the different rules for static it really makes sense that they are all called static. :-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜