7.1.1 存储类说明符
7.1.1 存储类说明符
1、存储类说明符包括:
storage-class-specifier:
auto
register
static
extern
mutable
对于给定的decl-specifier-seq,至多只能有一个存储类说明符。如果一个存储类说明符出现在某个decl-specifier-seq中,那么这个decl-specifier-seq可以不包含typedef说明符,但声明的init-declarator-list不能为空(全局的匿名联合体类型除外,但它必须声明为静态类型(9.5))。存储类说明符作用于列表中的每一个init-declarator声明的名字,但对于其他说明符声明的名字无效。在显式特化(
2、auto和register说明符只能作用于在区块(6.3)中声明的对象的名字和函数参数(8.4)。它们说明具名对象具有自动存储周期(
3、register说明符在语义上相当于auto说明符,并同时暗示编译器所声明的对象将被频繁使用。[注意:这个暗示可被编译器忽略,特别是当代码中含有对对象的取址操作时。]
4、static说明符可作用于对象、函数的名字以及匿名联合体(9.5)。静态函数不能在区块中声明;函数的参数也不能为静态类型。static说明符声明对象具有静态存储周期(
5、extern说明符只能作用于对象和函数的名字。extern说明符不能用于声明类成员或函数参数。对于使用extern说明符声明的名字的链接属性,参见3.5。
6、在名字空间作用域声明的名字,如果未指定存储类说明符,具有外部链接,除非在此之前被声明为内部链接并且不是const类型。声明为const的对象,如果没有显式的extern声明,具有内部链接属性。
7、对于同一个的实体所做的多次声明,其链接属性应该保持一致。也就是说,在给定的作用域内,多次对同一个对象名字或函数名字的同一个重载进行声明,每次声明必须具有相同的链接属性。当然,不同的重载函数可以具有不同的链接属性。例如:
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
(另注:在VC6.0中,诸如
char* g(); // g() has external linkage
static char* g() // error: inconsistent linkage
{ /* ... */ }
这样的声明是合法的。)
8、经过声明但未被定义的类名可被用于extern声明。这个声明只能用于不需要完全类类型的场合。例如:
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
}
mutable说明符只能作用于类数据成员(9.2)的名字,不能作用于已声明为const或static的名字,也不能作用于引用成员。例如:
class X {
mutable const int* p; // OK
mutable int* const q; // ill-formed
};
9、作用于类数据成员上的mutable说明符可屏蔽作用于类对象的const说明符,因而即使在类对象为const(