声明中的哪个位置可以放置存储类说明符?

Jam*_*lis 19 c++ declaration storage-class-specifier

例如,让我们考虑一下static存储类说明符.以下是此存储类说明符的有效和不正确用法的几个示例:

static int a;        // valid
int static b;        // valid

static int* c;       // valid
int static* d;       // valid
int* static e;       // ill-formed

static int const* f; // valid
int static const* g; // valid
int const static* h; // valid
int const* static i; // ill-formed

typedef int* pointer;
static pointer j;    // valid
pointer static k;    // valid
Run Code Online (Sandbox Code Playgroud)

(标记为"有效"的声明被Visual C++ 2012,g ++ 4.7.2和Clang ++ 3.1接受.标记为"格式错误"的声明被所有这些编译器拒绝.)

这看起来很奇怪,因为存储类说明符适用于声明的变量.它是声明的变量,而static不是声明的变量的类型.为什么ei形象k不对,但形式良好?

有效放置存储类说明符的规则是什么?虽然我static在此示例中使用过,但该问题适用于所有存储类说明符.优选地,完整的答案应引用C++ 11语言标准的相关部分并解释它们.

hex*_*ist 17

总之,声明说明符中的任何位置(参见ISO/IEC 14882-2012中的第7.1节),即在声明之前*.之后的限定符*与指针声明符关联,而不是类型说明符,并且在指针声明符static的上下文中没有意义.

请考虑以下情况:您可以在同一个声明列表中声明一个普通的int和一个指向int的指针,如下所示:

int a, *b;
Run Code Online (Sandbox Code Playgroud)

这是因为类型说明符是int,那么你使用的类型说明符有两个声明int,a以及指针声明符*a它声明的指针int.现在考虑:

int a, static b;  // error
int a, *static b; // error
int a, static *b; // error
Run Code Online (Sandbox Code Playgroud)

它应该看起来是错误的(因为它们是),原因(如第7.1和8.1节所定义)是因为C和C++要求您的存储说明符与您的类型说明符一起使用,而不是在您的声明符中.所以现在应该清楚的是,以下也是错误的,因为上述三个也是错误的:

int *static a; // error
Run Code Online (Sandbox Code Playgroud)

你最后一个例子,

typedef int* pointer;
static pointer j;    // valid
pointer static k;    // valid
Run Code Online (Sandbox Code Playgroud)

两者都是有效的并且都是等价的,因为pointer类型被定义为类型说明符,您可以按任何顺序放置类型说明符和存储规范.请注意,它们都是等价的,相当于说

static int *j;
static int *k;
Run Code Online (Sandbox Code Playgroud)

要么

int static *j;
int static *k;
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 5

根据7.1,C++声明的[简化]结构是

decl-specifier-seq init-declarator-list;
Run Code Online (Sandbox Code Playgroud)

根据7.1/1,存储类说明符属于最初的"公共"部分decl-specifier-seq.

Per 8/1 init-declarator-list是一系列声明符.

根据8/4,*指针声明的一部分是该序列中单个声明符的一部分.这立即意味着a之后的所有内容*都是该单个声明者的一部分.这就是您的某些存储类说明符展示位置无效的原因.声明符语法不允许包含存储类说明符.

基本原理是相当明显的:由于存储类说明符应该适用于整个声明中的所有声明符,因此它们被放置在声明的"公共"部分中.


我会说,一个更有趣(并且有些相关)的情况发生在可以出现在两个 decl-specifier-seq和单个声明const符中的说明符中,例如说明符.例如,在以下声明中

int const *a, *b;
Run Code Online (Sandbox Code Playgroud)

const适用于所有声明者还是仅适用于第一个?语法规定了前一种解释:const适用于所有声明者,即它是一部分decl-specifier-seq.