問題タブ [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++ - インライン定義された static const 整数メンバー変数のアドレスを取得しても ODR に違反しないのはなぜですか?
このようなものは、コンパイルされた場合、C++ の 1 つの定義規則に明らかに違反します。
something.h が複数のモジュールに含まれている場合、の定義A::val
が繰り返されるためです。ただし、これは許可されています。
私が理解しているように、このケースが問題ない理由B::val
は、 が整数型のコンパイル時の定数であるためです。そのため、コンパイラは本質的にすべての参照をB::val
リテラルで検索して置換できます3
(逆アセンブリを調べると、これが示されます)。まさにそれが行うことです)。したがって、最終製品にはある意味ゼロの定義があるB::val
ため、ODR は適用されません。ただし、次の点を考慮してください。
これは許可されており、この場合、一部のメモリ位置が の値を格納するために実際に確保されていることが逆アセンブリによって示されますC::val
。表面的には、これは、yetAnotherThing.h が複数のモジュールに含まれている場合、static const int val = 3
ストレージが「放出」されるため、ODR に違反するようになったことを意味します。それでも、コンパイラもリンカ (VC++2012) も文句を言いません。
なんで?これは、コンパイラ/リンカーの作成者が対処しなければならない不快な特殊なケースですか? もしそうなら、同じシステムを使用してケース 1 を機能させられないのはなぜですか?
(標準からの関連する引用は歓迎されますが、必ずしも質問に答えるとは限りません。標準で、pink_elephants
キーワードの使用によって数値 42 のすべてのインスタンスが 666 に置き換えられるべきであると述べられている場合、それはそれになりますが、私たちはなぜそのような奇妙なルールが存在するのか、まだ疑問に思っています。)
c++ - インライン関数宣言がリンクエラーであるヘッダーファイルを含む他のヘッダーファイルにインライン関数定義を置くのはなぜですか?
私は2つのヘッダーを持っています。
MSVC 2013 でリンク エラーが発生しました。翻訳単位が 1 つしかないので、「ODR」が原因ではないのでしょうか?
これで、header2.h をインクルードする test2.cpp ができました。したがって、リンカは現在 header2.h を見つけることができると思います。それでもリンク エラーが発生するのはなぜですか?
c++11 - クラス外の定義なしで static constexpr std::array にアクセスする
いくつかの配列を定義するクラスがあります。
ポイント.hpp
次に、メイン ファイルでこれらの配列を使用します。
main.cpp
C++11 と g++ 4.8.2 を使用してコードをコンパイルすると、次のリンカ エラーが発生します。
コンパイラがそこからオブジェクト ファイルを作成できるように、Points.cpp ファイルを作成しようとしました。
ポイント.cpp
しかし、それはリンカーエラーを修正しませんでした.
この質問に示すように、クラス宣言で C++ 11 の静的 constexpr として変数を初期化し、私が行っている方法で変数にアクセスできるという印象を受けました: https://stackoverflow.com /a/24527701/1991500
Points のコンストラクタを作成してから、クラスをインスタンス化する必要がありますか? 私は何を間違っていますか?
どんなフィードバックでも大歓迎です! ありがとう!
c++ - C++ - template-class の外でヘッダー内にメンバー関数を定義する
1 つのメンバー関数を持つ単純なクラス テンプレートを定義しました。これは、追加の (明示的な) 特殊化を使用してクラスの外部で定義され、クラスの外部でも定義されます。すべてが 1 つのヘッダーファイルに含まれています。このヘッダーを複数の翻訳単位に含めると、One-Definition-Rule が原因でリンカー エラーが発生します。
これまでのところすべて順調です。しかし、メンバー関数の定義をクラス本体内に配置すると、リンカー エラーがなくなり、関数をさまざまな翻訳単位で使用できるようになります。
私の質問は、なぜそのように機能するのですか? 私は MSVC 2012 を使用しています。ODR には、私が最初に考えた理由であるテンプレートに関するいくつかの例外があります。しかし、クラスの内外の「ベース」関数の定義は、ここで違いを生みます。
c++ - 個別の機能には個別のアドレスがありますか?
次の 2 つの関数を検討してください。
それは保証されてい&foo != &bar
ますか?
同様に、
それは保証されてい&foo<int> != &foo<double>
ますか?
私が知っている 2 つのリンカーは、関数定義を一緒に折り畳みます。
MSVC COMDAT は積極的に関数を折りたたむため、同じ実装を持つ 2 つの関数を 1 つの関数に変換できます。副作用として、2 つの関数は同じアドレスを共有します。これは違法であるという印象を受けましたが、標準のどこで違法になっているのかわかりません。
Gold リンカも関数を折り畳み、 asafe
とall
設定の両方を使用します。 safe
は、関数アドレスが取得された場合でも折り返されないことを意味しますが、 はall
アドレスが取得されても折り畳まれます。したがって、gold's foldsafe
は、あたかも関数が個別のアドレスを持っているかのように動作します。
折り畳みは予想外かもしれませんし、異なるアドレスを持つ別個の (同一の実装) 関数に依存するコードがあります (したがって折り畳むのは危険です) が、現在の C++ 標準では実際に違法ですか? (この時点では C++14) (当然 as-if のsafe
折りたたみは合法です)
c++ - インライン関数本体の潜在的な評価とテンプレート メンバーのインスタンス化
インラインとマークされた関数内に含まれる式は、いつ「潜在的に評価される」と見なされますか?
a.cpp
b.cpp
$(CCC) -c a.cpp; $(CCC) -c b.cpp; $(CCC) a.o b.o -o bin
インライン関数が定義されるとすぐに式が「潜在的に評価される」と見なされる場合、テンプレートをインスタンス化する必要があり、リンクが正常に行われると予想されます。代わりに、インラインで宣言された関数内の式が、そのような関数自体が ODR で使用されるようになったときにのみ「潜在的に評価される」ようになる$(CCC) -c a.cpp; $(CCC) -c b.cpp; $(CCC) a.o b.o -o bin
場合、リンク ステップで失敗することが予想されます。
これまでのところ、xl C++ 12 (リンクに成功) とさまざまなバージョンの gcc + clang 3.5 (すべてリンクに失敗) をテストしました。
正しい動作はどれですか? ここで 3 番目のオプションがありませんか?
python - scipy.ODR を使用した線形回帰が失敗する (解決時にフル ランクではない)
scipy.odr で線形回帰を試みていました。しかし、それはみじめに失敗しました。以前は scipy.odr が機能していましたが、コードにエラーは見られません。私が考えることができる唯一の理由は、勾配が小さすぎる可能性があるということですが、それがどのようにscipyを悩ませるのかわかりません。ご協力ありがとうございました。
コード:
これは結果の端末出力です。
そして、これは結果のグラフィックです:
編集:odr-regression の私のコードはhttp://docs.scipy.org/doc/scipy/reference/odr.htmlから来ています