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
不是声明的变量的类型.为什么e
和i
形象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)
根据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
.