c++ - 为什么在 2 个不同的 cpp 文件中定义内联全局函数会导致神奇的结果?

标签 c++ inline translation-unit

假设我有两个 .cpp 文件 file1.cppfile2.cpp:

// file1.cpp
#include <iostream>

inline void foo()
{
    std::cout << "f1\n";
}

void f1()
{
    foo();
}

// file2.cpp
#include <iostream>

inline void foo()
{
   std::cout << "f2\n";
}

void f2()
{
    foo();
}

并且在 main.cpp 我已经转发声明了 f1()f2():

void f1();
void f2();

int main()
{
    f1();
    f2();
}

结果(不依赖于构建,调试/发布构建的结果相同):

f1
f1

哇:编译器不知何故只从 file1.cpp 中挑选定义并在 f2() 中使用它。这种行为的确切解释是什么?

注意,将 inline 更改为 static 是解决此问题的方法。将内联定义放在未命名的命名空间中也可以解决问题,程序会打印:

f1
f2

最佳答案

这是未定义的行为,因为具有外部链接的同一内联函数的两个定义打破了 C++ 对可以在多个位置定义的对象的要求,称为一个定义规则:

3.2 One definition rule

...

  1. There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14),[...] in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then

6.1 each definition of D shall consist of the same sequence of tokens; [...]

这不是 static 函数的问题,因为一个定义规则不适用于它们:C++ 认为在不同翻译单元中定义的 static 函数独立于每个其他。

关于c++ - 为什么在 2 个不同的 cpp 文件中定义内联全局函数会导致神奇的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43736349/

相关文章:

c++ - 在没有移动构造函数的情况下,复制构造函数被调用?这是为什么?

c++ - 通过接口(interface)检索未知类型数据的类型安全方法

html - 如何在<div>内显示内联<span>?

html - 如何沿屏幕制作 150x150 正方形的 div

c++如何将类声明为文件的本地类

python - 确定一个 dll 是在调试中构建的还是使用 python 发布的

c++ - 打印对象数组的每个元素时出现问题

c - 调用内联函数时 undefined reference

c++ - 具有不同编译器的不同翻译单元中的内联函数标记未定义的行为?

c++ - 不同翻译单元中的模板实例