当我尝试这样做时:
int Var_1 =3, const Var_2 =34;
它抛出一个错误,我理解(多个)类型限定符 const
在多项声明中的第一个逗号之后不能出现(如上所述here)但是当使用指针引发限定符时,它会改变其行为“
int Var_1 =3, *const Var_2 = &Var_1; //works fine
有人可以解释一下吗?
答案 0 :(得分:4)
这与声明在C ++中工作的奇怪方式有关,它是从C继承的。
问题中显示的声明的一般结构如下:您有一系列说明符,后跟一个或多个逗号分隔的声明符,其中每个声明者可能有一个可选的初始值设定项。
关键字const
和int
是说明符,所以它们在开头。每个说明符都修改所有声明符。例如:
const int *x, y[10];
在此声明中,有两个说明符,即const
和int
,以及两个声明符,即*x
和y[10]
。两个说明符中的每一个都修改两个声明符。
说明符描述的类型信息只能在开头出现,因为所有说明符必须在所有声明符之前。这是语言规则。
但是,某些类型信息由声明者携带。显然,x
和y
在上述声明中具有不同的类型,即使它们被相同的说明符修改; x
是指针类型,而y
是数组类型。声明器可以被认为是由声明的实体的名称和一些运算符组成。 *
运算符创建指针,而[]
运算符创建数组。这些运算符可以组合和嵌套,并且可以用括号更改它们的优先级。
我们可以将*const Var_2
解释为声明符,将*const
视为生成const
限定指针的运算符。需要此语法,因为const int* p
生成指向const int
的指针,但不生成指向const
的{{1}}指针。因此,int
中的const
提供的角色与说明符中的角色不同,并且仅在语法上允许,因为它是*const Var_2
运算符的一部分。但是,单独*const
不是可以出现在声明符中的有效运算符,当您将它放在逗号后面时,它就不再是说明符了。
答案 1 :(得分:1)
如果没有详细说明,声明的语法是 decl-specifier-seq ,后跟 init-declarator-list ,后跟分号。< / p>
在您的声明中,int
是 decl-specifier-seq ,Var1 = 3, *const Var_2 = 34
是 init-declarator-list 。后一术语是指可能具有初始值设定项的逗号分隔的声明符列表。
声明符的定义涉及它必须是以下之一:
*
,&
,&&
或T::*
所以Var1
是声明者,因为它是一个标识符。 *const Var2
是第二个项目符号下的声明者。但const Var2
与上述任何规则都不匹配。
为什么规则是这样的?我无法准确地说出来,但我会假设添加一个规则,即#34;限定符声明符&#34;也是一个声明者会引入问题,例如对当前有效的声明进行模糊解析。
例如int const x, y;
。如果const x
是声明者,则可以通过两种不同的方式对其进行解析 - 其中一种y
为int
,另一种y
为const int
。
但是在实际规则中,由于const x
不是声明者,唯一可能的解析是int const
为 decl-specifier-seq 和{{ 1}}成为声明者列表。