【发布时间】:2011-10-14 03:58:58
【问题描述】:
我在一个奇怪的问题上花了几天时间,终于发现项目中有两个相同签名的inline函数,它们导致了这个问题。为了简化情况,这里举个例子:两个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()。所以我认为问题发生在链接时。是否可以说链接器随机选择一种实现并丢弃所有其他实现?
【问题讨论】:
-
您是否尝试过更高的警告详细程度(-Wall 等)?
-
我刚刚试过
-Wall -Wextra,还是没有警告。
标签: c++ compiler-construction linker inline redefinition