Reputation: 63775
I was of the impression that C++ applies the same special rules to a static const
integral type regardless of whether declared at namespace scope or declared within a class/struct/union.
Now I'm thinking that I've been taught Bad Things by non-compliant compilers.
static const int A = 1;
struct s
{
static const int A = 1;
};
Aside from the obvious difference in scope, How do A
and s::A
differ?
I'm curious specifically about C++ 03.
Upvotes: 6
Views: 513
Reputation: 254461
How do
A
ands::A
differ?
The biggest difference is that the declaration of A
is also a definition, while that of s::A
is not. I'm not sure what you mean by "special rules", but static
has a different meaning in each case.
At namespace scope, it gives it internal linkage so that the object is not visible outside the current translation unit. Note that the static
is redundant here, since constant variables at namespace scope have internal linkage by default.
At class scope, it means that there is a single object independent of any instantiation of the class.
when their usage will be replaced with their literal value?
Since both are integral constants with an initialiser in the declaration, both can be used in constant expressions, and the compiler is able to replace their values with compile-time constants.
Perhaps a more appropriate question is, when is a definition required?
In C++11, it is required if the variable is odr-used - roughly speaking, if you do anything that requires the variable's address rather than its value.
In C++03, I think it was required if the variable is used at all, although no diagnostic is required and many compilers will not complain if you only use its value. I could be wrong though; the old rules were rather convoluted and I'm happy to be able to forget them now.
when I can take the address of it?
That requires the variable to have a definition, in both C++03 and C++11. The definition allocates storage for the variable, so that it has an address.
when I need to separately define them?
A variable declaration at namespace scope is also a definition, unless you declare it extern
; so your first variable does not need a separate definition.
A variable declaration at class scope is not a definition; so your second variable does need a separate definition in C++03, and in C++11 if it is odr-used.
Upvotes: 0
Reputation: 153919
The keyword static
doesn't mean the same thing in class scope
and in namespace scope. In fact, it's use in namespace scope is
deprecated.
When declaring a variable at class scope, static
means that
there will be one single instance of the variable, with static
storage duration and lifetime. The declaration within the class
is not a definition; if the variable is used, it must be
defined in one (and only one) translation units; if it is not
defined, you have undefined behavior. (In practice, depending
on the use, either everything will work fine, or you will get an
error from the linker.) Note that if the declaration is for
a const
integral type, and contains an initialization, it is
not considered used if it is used in a context which requires
a constant integral expression (like the dimension of a C style
array). The simplest and surest thing is just to define it
somewhere.
When declaring a variable at namespace scope, static
means
that the name has internal linkage, rather than external; with
or without static
, the declaration is a definition (so there
should be no other definition in the program). In C++03, this
use was deprecated; use unnamed namespace instead. Note too
that if the variable itself is const
(top level const), then
it has internal linkage by default, so the static
has no
effect whatsoever. (If you need a const
variable with
external linkage, make it a class member, or define it
explicitly extern
, using an initializer to make it
a definition, rather than just a declaration.)
Upvotes: 6