Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What special rules does C++ apply to static const integral types?

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?

  • ...when their usage will be replaced with their literal value?
  • ...when I can take the address of it?
  • ...when I need to separately define them?

I'm curious specifically about C++ 03.

like image 955
Drew Dormann Avatar asked Dec 18 '12 15:12

Drew Dormann


1 Answers

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.)

like image 95
James Kanze Avatar answered Sep 25 '22 16:09

James Kanze