c++ - 如果重新定义一个内联函数呢?

标签 c++ compiler-construction linker inline redefinition

我在一个奇怪的问题上花了几天时间,最后发现项目中有两个具有相同签名的 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/

相关文章:

c++ - std::make_unique SFINAE 友好吗?

parsing - 有多少种方法来构建解析器?

Objective-C:变量被编译器优化掉

c++ - 什么是 "metadata operation failed"VS2008 链接器错误?

c++ - 如何强制 std::map::find() 按值搜索

c++ - Qt 2D 寻路游戏中的动画

c++ - 为什么编译器告诉我 vector<string> 未声明?

algorithm - 不可变语言如何高效地实现 set、concat、equals 等?

gcc - 你能在 ld 脚本中添加两个 SECTION 部分吗

android - 缺少 sync_val_compare_and_swap_1