What does 'const static' mean in C and C++?
Solution 1:
A lot of people gave the basic answer but nobody pointed out that in C++ const
defaults to static
at namespace
level (and some gave wrong information). See the C++98 standard section 3.5.3.
First some background:
Translation unit: A source file after the pre-processor (recursively) included all its include files.
Static linkage: A symbol is only available within its translation unit.
External linkage: A symbol is available from other translation units.
At namespace
level
This includes the global namespace aka global variables.
static const int sci = 0; // sci is explicitly static
const int ci = 1; // ci is implicitly static
extern const int eci = 2; // eci is explicitly extern
extern int ei = 3; // ei is explicitly extern
int i = 4; // i is implicitly extern
static int si = 5; // si is explicitly static
At function level
static
means the value is maintained between function calls.
The semantics of function static
variables is similar to global variables in that they reside in the program's data-segment (and not the stack or the heap), see this question for more details about static
variables' lifetime.
At class
level
static
means the value is shared between all instances of the class and const
means it doesn't change.
Solution 2:
It has uses in both C and C++.
As you guessed, the static
part limits its scope to that compilation unit. It also provides for static initialization. const
just tells the compiler to not let anybody modify it. This variable is either put in the data or bss segment depending on the architecture, and might be in memory marked read-only.
All that is how C treats these variables (or how C++ treats namespace variables). In C++, a member marked static
is shared by all instances of a given class. Whether it's private or not doesn't affect the fact that one variable is shared by multiple instances. Having const
on there will warn you if any code would try to modify that.
If it was strictly private, then each instance of the class would get its own version (optimizer notwithstanding).
Solution 3:
That line of code can actually appear in several different contexts and alghough it behaves approximately the same, there are small differences.
Namespace Scope
// foo.h
static const int i = 0;
'i
' will be visible in every translation unit that includes the header. However, unless you actually use the address of the object (for example. '&i
'), I'm pretty sure that the compiler will treat 'i
' simply as a type safe 0
. Where two more more translation units take the '&i
' then the address will be different for each translation unit.
// foo.cc
static const int i = 0;
'i
' has internal linkage, and so cannot be referred to from outside of this translation unit. However, again unless you use its address it will most likely be treated as a type-safe 0
.
One thing worth pointing out, is that the following declaration:
const int i1 = 0;
is exactly the same as static const int i = 0
. A variable in a namespace declared with const
and not explicitly declared with extern
is implicitly static. If you think about this, it was the intention of the C++ committee to allow const
variables to be declared in header files without always needing the static
keyword to avoid breaking the ODR.
Class Scope
class A {
public:
static const int i = 0;
};
In the above example, the standard explicitly specifies that 'i
' does not need to be defined if its address is not required. In other words if you only use 'i
' as a type-safe 0 then the compiler will not define it. One difference between the class and namespace versions is that the address of 'i
' (if used in two ore more translation units) will be the same for the class member. Where the address is used, you must have a definition for it:
// a.h
class A {
public:
static const int i = 0;
};
// a.cc
#include "a.h"
const int A::i; // Definition so that we can take the address