类型限定符出现在多项声明中(用指针表现出奇怪的行为)

时间:2017-11-21 06:42:03

标签: c++

当我尝试这样做时:

   int Var_1 =3, const Var_2 =34;

它抛出一个错误,我理解(多个)类型限定符 const在多项声明中的第一个逗号之后不能出现(如上所述here)但是当使用指针引发限定符时,它会改变其行为“

   int Var_1 =3, *const Var_2 = &Var_1; //works fine

有人可以解释一下吗?

2 个答案:

答案 0 :(得分:4)

这与声明在C ++中工作的奇怪方式有关,它是从C继承的。

问题中显示的声明的一般结构如下:您有一系列说明符,后跟一个或多个逗号分隔的声明符,其中每个声明者可能有一个可选的初始值设定项

关键字constint是说明符,所以它们在开头。每个说明符都修改所有声明符。例如:

const int *x, y[10];

在此声明中,有两个说明符,即constint,以及两个声明符,即*xy[10]。两个说明符中的每一个都修改两个声明符。

说明符描述的类型信息只能在开头出现,因为所有说明符必须在所有声明符之前。这是语言规则。

但是,某些类型信息由声明者携带。显然,xy在上述声明中具有不同的类型,即使它们被相同的说明符修改; 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是声明者,则可以通过两种不同的方式对其进行解析 - 其中一种yint,另一种yconst int

但是在实际规则中,由于const x不是声明者,唯一可能的解析是int const decl-specifier-seq 和{{ 1}}成为声明者列表。