Спецификаторы класса хранения:
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-specifier — end 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]).