Files
cppdraft_translate/cppdraft/dcl/stc.md
2025-10-25 03:02:53 +03:00

8.5 KiB

[dcl.stc]

9 Declarations [dcl]

9.2 Specifiers [dcl.spec]

9.2.2 Storage class specifiers [dcl.stc]

1

#

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.

If astorage-class-specifier appears in a decl-specifier-seq, there can be notypedef specifier in the same decl-specifier-seq and the init-declarator-list or member-declarator-list of the declaration shall not be empty (except for an anonymous union declared in a namespace scope ([class.union.anon])).

Thestorage-class-specifier applies to the name declared by eachinit-declarator in the list and not to any names declared by other specifiers.

[Note 1:

See [temp.expl.spec] and [temp.explicit] for restrictions in explicit specializations and explicit instantiations, respectively.

— end note]

2

#

[Note 2:

A variable declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.

— end note]

3

#

The thread_local specifier indicates that the named entity has thread storage duration ([basic.stc.thread]).

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.

4

#

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 have static storage duration ([basic.stc.static]), unless accompanied by thethread_local specifier, which declares the variable to have thread storage duration ([basic.stc.thread]).

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

5

#

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

[Note 3:

The extern keyword can also be used inexplicit-instantiations andlinkage-specifications, but it is not astorage-class-specifier in such contexts.

— end note]

6

#

All declarations for a given entity shall give its name the same linkage.

[Note 4:

The linkage given by some declarations is affected by previous declarations.

Overloads are distinct entities.

— end note]

[Example 1: static char* f(); // f() has internal linkagechar* f() // f() still has internal linkage{ /* ... / }char g(); // g() has external linkagestatic char* g() // error: inconsistent linkage{ /* ... */ }void h();inline void h(); // external linkageinline void l();void l(); // external linkageinline void m();extern void m(); // external linkagestatic void n();inline void n(); // internal linkagestatic int a; // a has internal linkageint a; // error: two definitionsstatic int b; // b has internal linkageextern int b; // b still has internal linkageint c; // c has external linkagestatic int c; // error: inconsistent linkageextern int d; // d has external linkagestatic int d; // error: inconsistent linkage — end example]

7

#

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 2: struct S;extern S a;extern S f();extern void g(S);

void h() { g(a); // error: S is incomplete f(); // error: S is incomplete} — end example]

8

#

The mutable specifier shall appear only in the declaration of a non-static data member ([class.mem]) whose type is neither const-qualified nor a reference type.

[Example 3: class X {mutable const int* p; // OKmutable int* const q; // error}; — end example]

9

#

[Note 5:

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]