問題タブ [one-definition-rule]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 関数へのポインターと ODR
ODR に関する質問はたくさんありますが、探しているものが見つからないので、これが重複していたり、タイトルが不適切だったりしたら申し訳ありません。
次の点を考慮してください。
これは、 type ごとに一意の識別子を定義しようとする私の試みを単純化しすぎたものであり、異なるコンパイル ユニット間で一意のままであることを願っています。
T
特に、 のような具象型が与えられ、std::string
2 つの異なるコンパイル単位がヘッダー ファイルに上記のコードを含むと仮定すると、次の式が必要です。
両方の単位で( type の) 同じ値を取るため、t(*)()
type の一意の識別子として機能しT
ます。
値は関数のアドレスなtype<T>
ので、問題はプログラム内type<T>
で一意の関数が一定義規則で保証されているかどうかです。iso 3.2/3 は言う
すべてのプログラムには、そのプログラムで ODR で使用されるすべての非インライン関数または変数の定義が 1 つだけ含まれている必要があります。
どこで 3.2/2
名前が潜在的に評価される式または [...] として表示されるオーバーロードされていない関数は、[...] でない限り、odr で使用されます。
アドレスが取得された場合、関数は非インラインであると想定します(ただし、標準では見つかりません)。
iso 3.2/5 には多くの例外がリストされていますが、関数への唯一の参照は
外部リンケージを持つインライン関数、[...]、非静的関数テンプレート、[...]、クラス テンプレートのメンバー関数、または一部のテンプレート パラメーターが指定されていないテンプレートの特殊化 [...]
ここではそうではないようです。
検証可能な例では、複数のファイルが必要になります。実際、 Dieter Lückingによって失敗したと主張されている例が示されていますが、私の場合は失敗していません (これを「保証」とは見なしません)。
それで、これはうまくいくでしょうか?
c++ - C ++ 14で変数がodr使用されるのはいつですか?
C++14 ドラフト (N3936) は、§3.2/3 で次のように述べています。
名前が潜在的に評価される式 ex として表示される変数 x は、左辺値から右辺値への変換 (4.1) を x に適用して、重要な関数を呼び出さない定数式 (5.19) を生成しない限り、odr で使用されます。 x はオブジェクトであり、ex は式 e の潜在的な結果のセットの要素です。ここで、左辺値から右辺値への変換 (4.1) が e に適用されるか、e は破棄値式 (節 5) です。
これは私には意味がありません。式e
が破棄された値の式であるかどうかは、使用されるコンテキストに依存しますe
。expression-statement (§6.2) で使用されるすべての式は、破棄された値の式です。左辺値から右辺値への変換が適用される場合は、使用されるe
コンテキストにも依存しますe
。
さらに、式が別の式の潜在的な結果のセットにあるとはどういう意味ですか。セットのメンバーシップを決定できるようにするには、式が等しいという概念が必要です。しかし、参照透過性がないため、これをどのように達成できるかわかりません。
これが C++11 から C++14 に変更されたのはなぜですか? そして、これはどのように解釈されるべきですか?このままでは、意味がありません。
c++ - C++11 標準の §3.2/2 で、この文は何を意味していますか?
この文は、§3.2/2 の一部です。
名前が潜在的に評価される式として表示される変数は、それが定数式 (5.19) に表示されるための要件を満たし、左辺値から右辺値への変換 (4.1) がすぐに適用されるオブジェクトでない限り、odr-usedです。
上記の太字の文は正確にはどういう意味ですか?
編集:
これが重複と見なされる質問に対する答えは、私の質問に答えることができるものは何も言いません。
c++ - C++ での 1 つの定義ルール
C++ 標準によると:
変換単位には、変数、関数、クラス型、列挙型、またはテンプレートの複数の定義が含まれてはなりません。
ODR が実際にどのように機能するか説明してもらえますか?
c++ - ヘッダーで名前のない名前空間を使用すると、ODR 違反がどのように発生しますか?
Google C++ スタイル ガイドの名前空間セクションには、「ヘッダー ファイルで名前のない名前空間を使用すると、C++ One Definition Rule (ODR) に違反する可能性があります」と記載されています。
実装ファイルで名前のない名前空間を使用しないと ODR 違反が発生する理由は理解できますが、ヘッダーで使用するとどのように発生するかはわかりません。これがどのように違反を引き起こす可能性がありますか?