最小限のコード:インライン関数の定義が異なると、定義されていない動作ですか?
// --------inline.h--------
struct X {
static inline void foo();
};
#ifdef YES
inline void X::foo() { cout << "YES\n"; }
#else
inline void X::foo() { cout << "NO\n"; }
#endif
// --------file1.cpp--------
#define YES // <----
#include"inline.h"
void fun1()
{
X::foo();
}
// --------file2.cpp--------
#include"inline.h"
void fun2()
{
X::foo();
}
我々はfun1()
とfun2()
を呼び出した場合、その後、彼らは同じX::foo()
の異なる機能体を参照している意味し、それぞれYES
とNO
を印刷します。
このコードにかかわらず、私の質問は
これは明確に定義されているか未定義の動作ですか?
名前が異なる2つの異なるファイルに2つの異なるフリー・ファンクション(クラス・メンバーではない)を使用したい場合は、 'static'キーワード(または匿名名前空間)を使用してそれらを分離できます。 file2.cppの関数をstaticとマークすると、リンク中にほかの.cppファイルが認識できなくなります。これは非常に大きなプログラムの場合に便利です。ここでは、一般的な名前がすでに関数によってどのように使われているかを必ずしも確かめることができません。 – Crashworks
この場合、inline.hと#defineハックは本当に必要ありません。 file1.cppでは "void X :: foo()"(インラインでもインラインでも)を片方だけ定義し、file2.cppではもう一方を定義すれば、まったく同じ動作になります。 – abarnert
@abarnert: 'inline'を省略すると、1つの定義ルール違反になります。非インライン関数は3.2段落3、インライン関数は3.2段落5でカバーされます。多くの(ほとんどの)リンカーは非インライン違反をキャッチします。少なくとも私はインライン違反をキャッチしていません。 –