3

我打算向 GCC 提交一个错误,但后来意识到如果我对标准的解释是正确的,那是核心语言缺陷,而不是编译器错误。

当数组类型的静态数据成员在类范围之外定义时,在类范围内查找数组绑定中的标识符。

§9.4.2 [class.static.data] 说“静态数据成员定义中的初始化表达式在其类 (3.3.7) 的范围内”,但没有说明声明符本身。这似乎是声明器中唯一的名称查找上下文。

§8.4.2 [dcl.array] 没有提到数组绑定的范围,因此默认情况下,表达式在封闭范围内进行评估,即命名空间。

class X {
  static int const size = some_complicated_metafunction<>::value;
  static int arr[ size ];
};

// "size" should be qualified as "X::size", which is an access violation.
int X::arr[ size ] = {};

问题是,如果数组绑定没有在类范围内评估,则无法访问私有类成员,并且some_complicated_metafunction<>必须重新指定。数组绑定需要与初始化程序相同的范围,原因与初始化程序基本相同。(虽然没有那么强大,因为常量表达式总是可以重新计算,这与私有对象的地址不同。)

我是否遗漏了某些东西或 DR 是否正常?

4

1 回答 1

4

我认为成员定义中绑定的数组在类范围内。标准 3.3.7/1:

以下规则描述了类中声明的名称范围。

...

5) 延伸到或超过类定义结尾的声明的潜在范围也延伸到由其成员定义定义的区域,即使成员是在类外部的词法定义的(这包括静态数据成员定义、嵌套类定义、成员函数定义(包括成员函数体和此类定义的声明部分的任何部分,其跟在 declarator-id之后,包括参数声明子句和任何默认参数(8.3.6)......

这里的声明者 ID 是X::arr.

于 2012-04-08T11:35:35.853 回答