私は奇妙な問題で何日も過ごし、最後にプロジェクト内に同じ署名の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を使用していた、と私は打ち鳴らす++ 2.9、同じ結果でテスト済み)
g++ -O3 a.cpp b.cpp -o a.out && ./a.out
のように、最適化をオンにすると、それは0 1
今回の場合は発生しません
。
私の質問は、結果やコンパイルの実行方法に関係なく、私がinline
関数を複数回定義したことについてはエラーも警告もありません。このような状況で、コンパイラやリンカには何が起こりますか?
EDIT:
は、両方のファイルがレコードecho()
を持って
nm a.o b.o | c++filt
オブジェクトファイル内のシンボルを見てみましょう。だから問題はリンク時に起こると思う。リンカーがランダムに1つの実装を選択し、他のすべてを破棄したと言えるでしょうか? C++標準で
警告をより詳細に表示しようとしましたか(-Wallなど)? – schnaader
私は '-Wall -Wextra'を試しましたが、まだ警告はありません。 – neuront