Drew Dormann
Drew Dormann

Reputation: 63775

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?

I'm curious specifically about C++ 03.

Upvotes: 6

Views: 513

Answers (2)

Mike Seymour
Mike Seymour

Reputation: 254461

How do A and s::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

James Kanze
James Kanze

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

Related Questions