私は奇妙な問題に何日も費やしましたが、最終的inline
に、プロジェクトに同じ署名の 2 つの関数があり、それらが問題の原因であることを発見しました。状況を簡単にするために、以下に例を示します: 2 つの cpp ファイル:
a.cpp
#include <iostream>
void b();
inline void echo()
{
std::cout << 0 << std::endl;
}
int main()
{
echo();
b();
return 0;
}
および b.cpp
#include <iostream>
inline void echo()
{
std::cout << 1 << std::endl;
}
void b()
{
echo();
}
inline
関数echo
のシグネチャは同じですが、実装が異なることに注意してください。コンパイルして実行
g++ a.cpp b.cpp -o a.out && ./a.out
または、このように
g++ a.cpp -c
g++ b.cpp -c
g++ a.o b.o -o a.out
./a.out
印刷し0 0
ます。(私はそのためにg ++ 4.6.1を使用していました.clang ++ 2.9でテストしましたが、同じ結果です)
次のように最適化をオンにすると、それは起こりません
g++ -O3 a.cpp b.cpp -o a.out && ./a.out
0 1
今回です。
私の質問は、結果やコンパイルの実行方法に関係なく、inline
関数を複数回定義したというエラーや警告さえないということです。このような状況では、コンパイラとリンカは一体どうなるのでしょうか?
編集:
オブジェクトファイルのシンボルを見てください
nm a.o b.o | c++filt
両方のファイルにレコードがありecho()
ます。したがって、問題はリンク時に発生すると思います。リンカーはランダムに 1 つの実装を選択し、他のすべてを破棄すると言えますか?