我在一个奇怪的问题上花了几天时间,最后发现项目中有两个具有相同签名的 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()
。所以我认为问题发生在链接时。是否可以说链接器随机选择一个实现并丢弃所有其他实现?
最佳答案
在 C++ 标准中规定内联函数的所有定义都应相同,但不需要诊断。也就是说,您的程序不是有效的 C++ 程序,但实现有权不检测该错误。
参见第 3.2.5 条。在这里发帖太长了。
关于c++ - 如果重新定义一个内联函数呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6843202/