次のコードが入っていて、警告やエラーが生成さA.cpp
れ ていないのに、inが2回呼び出され、 inが呼び出されない場合。B.cpp
Initializer::Initializer()
B.cpp
A.cpp
static int x = 0;
struct Initializer
{
Initializer()
{
x = 10;
}
};
static Initializer init;
これは単一定義規則に違反し、未定義の動作を引き起こしているため、これは完全に正常だと思います。ただし、次のように、コンストラクター定義をいずれかまたは両方のファイルのクラス宣言の外に移動すると、次のようになります。
static int x = 0;
struct Initializer
{
Initializer();
};
Initializer::Initializer()
{
x = 10;
}
static Initializer init;
リンカは突然、エラーが発生して言うほど賢くなりますone or more multiply defined symbols found
。ここで何が変わり、なぜそれが重要だったのですか?リンカーは常にODRの破損を検出できるはずだと思っていたでしょうが、検出できない場合はどうなりますか?
私が間違っている場合は誰かが私を訂正しますが、私の理論では、テンプレート化されたコード(定義は常にヘッダーにあります)を使用すると、多くのコンパイル単位で定義が重複することになります。それらはすべて同一であるため、リンカーが1つを選択し、他を孤立させるかどうかは問題ではありませんが、複数の定義があるか、テンプレートが機能しないことは間違いありません。