When refactoring away some #defines
I came across declarations similar to the following in a C++ header file:
static const unsigned int VAL = 42;
const unsigned int ANOTHER_VAL = 37;
The question is, what difference, if any, will the static make? Note that multiple inclusion of the headers isn't possible due to the classic #ifndef HEADER
#define HEADER
#endif
trick (if that matters).
Does the static mean only one copy of VAL
is created, in case the header is included by more than one source file?
The
static
means that there will be one copy ofVAL
created for each source file it is included in. But it also means that multiple inclusions will not result in multiple definitions ofVAL
that will collide at link time. In C, without thestatic
you would need to ensure that only one source file definedVAL
while the other source files declared itextern
. Usually one would do this by defining it (possibly with an initializer) in a source file and put theextern
declaration in a header file.static
variables at global level are only visible in their own source file whether they got there via an include or were in the main file.Editor's note: In C++,
const
objects with neither thestatic
norextern
keywords in their declaration are implicitlystatic
.The static will mean you get one copy per file, but unlike others have said it's perfectly legal to do so. You can easily test this with a small code sample:
test.h:
test1.cpp:
test2.cpp:
Running this gives you this output:
const
variables in C++ have internal linkage. So, usingstatic
has no effect.a.h
one.cpp
two.cpp
If this were a C program, you would get 'multiple definition' error for
i
(due to external linkage).The static declaration at this level of code means that the variabel is only visible in the current compilation unit. This means that only code within that module will see that variable.
if you have a header file that declares a variable static and that header is included in multiple C/CPP files, then that variable will be "local" to those modules. There will be N copies of that variable for the N places that header is included. They are not related to each other at all. Any code within any of those source files will only reference the variable that is declared within that module.
In this particular case, the 'static' keyword doesn't seem to be providing any benefit. I might be missing something, but it seems to not matter -- I've never seen anything done like this before.
As for inlining, in this case the variable is likely inlined, but that's only because it's declared const. The compiler might be more likely to inline module static variables, but that's dependent on the situation and the code being compiled. There is no guarantee that the compiler will inline 'statics'.
const variables are by default static in C++, but extern C. So if you use C++ this no sense what construction to use.
(7.11.6 C++ 2003, and Apexndix C has samples)
Example in compare compile/link sources as C and C++ program:
Static prevents another compilation unit from externing that variable so that the compiler can just "inline" the variable's value where it is used and not create memory storage for it.
In your second example, the compiler cannot assume that some other source file won't extern it, so it must actually store that value in memory somewhere.