我在一个奇怪的问题上花费了几天时间,最终发现项目中有两个相同签名的inline
函数导致了这个问题。为了简化情况,这里举个例子:两个cpp文件:
a.cpp
#include <iostream>
void b();
inline void echo()
{
std::cout << 0 << std::endl;
}
int main()
{
echo();
b();
return 0;
}
and 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()
。所以我认为问题发生在链接时。可以说链接器随机选择一个实现并丢弃所有其他实现吗?
-Wall -Wextra
,仍然没有警告。 - neuront