次のプログラムで単一定義規則に違反していますか?
// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_
namespace {
inline int foo() {
return 1;
}
}
inline int bar() {
return foo();
}
#endif
//EOF
と
// m1.cpp
#include "foo.hpp"
int m1() {
return bar();
}
//EOF
と
// m2.cpp
#include "foo.hpp"
int m2() {
return bar();
}
//EOF
そして最後に
// main.cpp
#include <iostream>
int m1();
int m2();
int main(int, const char* [])
{
int i = m1();
int j = m2();
std::cout << (i+j) << std::endl;
return 0;
}
// EOF
foo()
上記では、それは匿名の名前空間で定義されていることに注意してください。したがって、各翻訳単位は独自のバージョンを取得することを期待しているので、ODRの違反はありませんm1.cpp
。m2.cpp
一方、bar()
は、たまたま2つの異なるを呼び出す単純な古いインライン関数foo
です。それで、それはODRに違反しますよね?
更新:
以前は、定義にマクロがあり、foo
それが返す値を変更し、マクロを含める前にそれぞれ異なる方法でマクロm1
を定義していました。(そして、その前の例では、期待した値以外の値で出力するバイナリを生成します。)しかし、実際には、このプログラムは、本体が同一であってもODRに違反します。m2
foo.hpp
g++
(i+j)
foo()