10 Declarations [dcl.dcl]

10.1 Specifiers [dcl.spec]

10.1.1 Storage class specifiers [dcl.stc]

Спецификаторы класса хранения:

storage-class-specifier:
	static
	thread_local
	extern
	mutable

Максимум один storage-class-specifierдолжен появиться в данном задании decl-specifier-seq, за исключением того, что thread_­local может появиться с помощью static или extern. Если он thread_­local появляется в любом объявлении переменной, он должен присутствовать во всех объявлениях этого объекта. Если a storage-class-specifier появляется в a decl-specifier-seq, в нем не может быть typedef спецификатора, decl-specifier-seqи init-declarator-listor member-declarator-list объявления не должно быть пустым (за исключением анонимного объединения, объявленного в именованном пространстве имен или в глобальном пространстве имен, которое должно быть объявлено static ([class.union.anon])). storage-class-specifierОтносится к имени , объявленному каждому init-declaratorв списке , а не какие - либо имена , объявленных другими спецификаторами. storage-class-specifier Кроме thread_­local не должно быть указано в explicit specialization или в explicit instantiation директиве.

[ Note: Переменная, объявленная без storage-class-specifier области действия блока или объявленная как параметр функции, automatic storage duration по умолчанию. ]end note

Спецификатор thread_­local указывает, что названный объект имеет thread storage duration. Он должен применяться только к именам переменных пространства имен или области блока и к именам статических элементов данных. Когда thread_­local применяется к переменной области блока storage-class-specifier static , подразумевается, если storage-class-specifierв decl-specifier-seq.

Спецификатор static может применяться только к именам переменных и функций и к anonymous unions. Внутриstatic блока не может быть ни объявлений функций, ни каких-либо static параметров функции. static Спецификатор используется в объявлении переменной объявляет переменную , чтобы static storage duration, если не будет сопровождаться thread_­local спецификатора, который объявляет переменную иметь thread storage duration. static Спецификатор можно использовать в объявлениях членов класса; [class.static] описывает его эффект. О связи имени, объявленного с помощью static спецификатора, см [basic.link].

Спецификатор extern можно применять только к именам переменных и функций. Спецификатор extern нельзя использовать в объявлении членов класса или параметров функции. О связи имени, объявленного с помощью спецификатора, см . [ Ключевое слово также может быть использовано в и , но это не в таких условиях. ] extern [basic.link]Note: extern explicit-instantiations linkage-specificationsstorage-class-specifierend note

Связи, подразумеваемые последовательными декларациями для данного объекта, должны быть согласованы. То есть в пределах заданной области каждое объявление, объявляющее одно и то же имя переменной или одну и ту же перегрузку имени функции, должно подразумевать одну и ту же связь. Однако каждая функция в данном наборе перегруженных функций может иметь разные связи. [Example:

static char* f();               // f() has internal linkage
char* f()                       // f() still has internal linkage
  { /* ... */ }

char* g();                      // g() has external linkage
static char* g()                // error: inconsistent linkage
  { /* ... */ }

void h();
inline void h();                // external linkage

inline void l();
void l();                       // external linkage

inline void m();
extern void m();                // external linkage

static void n();
inline void n();                // internal linkage

static int a;                   // a has internal linkage
int a;                          // error: two definitions

static int b;                   // b has internal linkage
extern int b;                   // b still has internal linkage

int c;                          // c has external linkage
static int c;                   // error: inconsistent linkage

extern int d;                   // d has external linkage
static int d;                   // error: inconsistent linkage

end example]

В объявлении можно использовать имя объявленного, но неопределенного класса extern . Такое объявление может использоваться только способами, не требующими полного типа класса. [Example:

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]

Спецификатор mutable должен появляться только в объявлении объекта non-static data member , тип которого не является ни константным, ни ссылочным типом. [Example:

class X {
  mutable const int* p;         // OK
  mutable int* const q;         // ill-formed
};

end example]

Спецификатор mutable члена данных класса обнуляет const спецификатор, примененный к содержащему объекту классу, и разрешает модификацию изменяемого члена класса, даже если остальной частью объекта является const ([dcl.type.cv]).