だから私は2つの別々の翻訳単位でこのコードを持っています:
// a.cpp
#include <stdio.h>
inline int func() { return 5; }
int proxy();
int main() { printf("%d", func() + proxy()); }
// b.cpp
inline int func() { return 6; }
int proxy() { return func(); }
正常にコンパイルされると、結果は10
. -O3 (インライン展開) でコンパイルすると、11
.
に対して ODR 違反を行ったことは明らかですfunc()
。
異なるdllのソースをより少ないdllにマージし始めたときに現れました。
私が試してみました:
- GCC 5.1
-Wodr
(必要-flto
) - ゴールドリンカー
-detect-odr-violations
ASAN_OPTIONS=detect_odr_violation=1
アドレス サニタイザーを使用してインストルメント化されたバイナリを実行する前に設定します。
Asan は、他の ODR 違反をキャッチできると思われます (異なるタイプのグローバル変数またはそのようなもの...)
これは C++ の非常に厄介な問題であり、それを検出するための信頼できるツールがないことに驚いています。
おそらく、私が試したツールの 1 つを悪用したのでしょうか? または、これには別のツールがありますか?
編集:
func()
大幅に異なる 2 つの実装を作成しても、同じ量の命令にコンパイルされないため、問題に気付かないままです。
これは、クラス本体内で定義されたクラス メソッドにも影響します。それらは暗黙的にインライン化されます。
// a.cpp
struct A { int data; A() : data(5){} };
// b.cpp
struct A { int data; A() : data(6){} };
多くのコピー/貼り付けとその後の小さな変更を伴うレガシーコードは楽しいものです。