7

widget.hpp以下の内容のヘッダー ファイルがあるとします。

constexpr int foo = 10;

struct widget
{
    int bars[foo];
};

...そして、 のみを含む 2 つのソース ファイルから生成された 2 つの翻訳単位がありwidget.hppますfoo

foo内部リンケージがありますが、定数式でもあります。以下に引用する C++11 標準の 3.2.6 を読んだところ、要件 2 が静的データ メンバーのみを参照していない場合、これは整形式です。


3.2.6 要件 #2:

D の各定義では、対応する名前は、3.4 に従って検索され、D の定義内で定義されたエンティティを参照するか、またはオーバーロードの解決 (13.3) および部分的なテンプレートの特殊化の一致 (14.8) の後に同じエンティティを参照する必要があります。 .3)ただし、オブジェクトが D のすべての定義で同じリテラル型を持ち、オブジェクトが定数式 (5.19) で初期化されている場合、名前は内部リンケージまたはリンケージなしの非揮発性 const オブジェクトを参照できます。オブジェクトは ODR 使用されておらず、オブジェクトは D のすべての定義で同じ値を持っています

4

3 に答える 3

1

の複数の定義については、 3.2.3 に従って、定数式に出現するための要件を満たしているため、odr を使用しているとはfoo思いません。foo

名前が潜在的に評価される式 ex として表示される変数 x は、x が定数式に表示されるための要件を満たすオブジェクトでない限り、odr で使用されます。

したがって、odr-used ではないため、odr-rule は適用されません。3.2.4:

すべてのプログラムには、そのプログラムで ODR で使用されるすべての非インライン関数または変数の定義が 1 つだけ含まれている必要があります。

の 2 つの異なる定義についてはwidget、3.2.6 に従って十分に類似しているかどうか。N3485 3.2.6:

オブジェクトが D のすべての定義で同じリテラル型 [はい、両方とも int] を持ち、オブジェクトが初期化されている場合、名前は内部 [constexpr は内部] またはリンケージなしの const オブジェクト [はい、constexpr は const] を参照できます。定数式 [yes, 10] を使用し、オブジェクトの値 (ただしアドレスではない) が使用され、オブジェクトは D のすべての定義で同じ値 [yes, 10] を持ちます。

そのため、名前fooが 2 つの異なる TU 内の 2 つの異なるエンティティを参照している場合でも、これら 2 つのエンティティは所定の要件を満たしています。

(実際には、コンパイラが 2 つのクラスを同じようにレイアウトするため、これは機能します。したがって、2 つの TU から生成されたコードは互換性があります。)

于 2013-06-17T00:54:20.730 に答える