[dcl.stc] (original) (raw)
9 Declarations [dcl.dcl]
9.2 Specifiers [dcl.spec]
9.2.1 Storage class specifiers [dcl.stc]
The storage class specifiers are
storage-class-specifier: static thread_local extern mutable
At most one storage-class-specifier shall appear in a givendecl-specifier-seq, except that thread_local may appear with static orextern.
If thread_local appears in any declaration of a variable it shall be present in all declarations of that entity.
Thestorage-class-specifier applies to the name declared by eachinit-declarator in the list and not to any names declared by other specifiers.
It shall be applied only to the declaration of a variable of namespace or block scope, to a structured binding declaration ([dcl.struct.bind]), or to the declaration of a static data member.
When thread_local is applied to a variable of block scope thestorage-class-specifier static is implied if no otherstorage-class-specifier appears in thedecl-specifier-seq.
The static specifier shall be applied only to the declaration of a variable or function, to a structured binding declaration ([dcl.struct.bind]), or to the declaration of an anonymous union ([class.union.anon]).
There can be nostatic function declarations within a block, nor anystatic function parameters.
A static specifier used in the declaration of a variable declares the variable to havestatic storage duration, unless accompanied by thethread_local specifier, which declares the variable to havethread storage duration.
A static specifier can be used in declarations of class members; [class.static] describes its effect.
For the linkage of a name declared with a static specifier, see [basic.link].
The extern specifier shall be applied only to the declaration of a variable or function.
The extern specifier shall not be used in the declaration of a class member or function parameter.
For the linkage of a name declared with an extern specifier, see [basic.link].
The linkages implied by successive declarations for a given entity shall agree.
That is, within a given scope, each declaration declaring the same variable name or the same overloading of a function name shall imply the same linkage.
[ Example
:
static char* f();
char* f()
{ }
char* g();
static char* g()
{ }
void h(); inline void h();
inline void l(); void l();
inline void m(); extern void m();
static void n(); inline void n();
static int a;
int a;
static int b;
extern int b;
int c;
static int c;
extern int d;
static int d;
— end example
]
The name of a declared but undefined class can be used in anextern declaration.
Such a declaration can only be used in ways that do not require a complete class type.
[ Example
:
struct S; extern S a; extern S f(); extern void g(S);
void h() {
g(a);
f();
}
— end example
]
The mutable specifier shall appear only in the declaration of a non-static data memberwhose type is neither const-qualified nor a reference type.
[ Example
:
class X {
mutable const int* p;
mutable int* const q;
};
— end example
]
[ Note
:
The mutable specifier on a class data member nullifies aconst specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const ([basic.type.qualifier], [dcl.type.cv]).
— end note
]