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に続くそのような定義のdeclarator部分の任意の部分を含み、parameter-declaration-clauseおよびデフォルト引数(8.3.6)を含みます。..

ここで、declarator-idはX::arrです。

于 2012-04-08T11:35:35.853 に答える