C++ 代码在不同的优化标志下表现不同

Yux*_*xai 0 c++ language-lawyer

有四个文件,header.hA.cppB.cppmain.cpp

// header.h
struct test {
  static inline int get();
};
Run Code Online (Sandbox Code Playgroud)
// a.cpp
#include "header.h"
int testA() { return test::get(); }
int test::get() { return 0; }
Run Code Online (Sandbox Code Playgroud)
// b.cpp
#include "header.h"
int testB() { return test::get(); }
int test::get() { return 1; }
Run Code Online (Sandbox Code Playgroud)
// main.cpp
#include <cstdio>
int testA();
int testB();

int main() {
  printf("%d %d\n", testA(), testB());
}
Run Code Online (Sandbox Code Playgroud)

编译时g++ -o main A.cpp B.cpp main.cpp -O0二进制输出两个相同的数字,而-O3始终输出0 1.

另外,如果我将匿名名称空间添加到header.h,即

// header.h
namespace {
struct test {
  static inline int get();
}
}
Run Code Online (Sandbox Code Playgroud)

然后-O0还给出0 1

test::get()但如果更改为全局函数,我无法使用匿名名称空间编译代码

// header.h
namespace {
static inline int test_get(); 
}
// A.cpp
#include "header.h"
int testA() { return test_get(); }
//int test_get() { return 0; }
//namespace { int test_get() { return 0; }
// failed to compile neither with or without namespace
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下这里的规则吗?

use*_*570 5

有人可以解释一下这里的规则吗?

该程序格式错误,无需进行诊断,如下所述。

来自内联说明符文档

具有外部链接(例如未声明为静态)的内联函数或变量(C++17 起)具有以下附加属性:

  • 程序中可能有多个内联函数或变量的定义(C++17 起),只要每个定义出现在不同的翻译单元中并且(对于非静态内联函数和变量(C++17 起) ))所有定义都是相同的。例如,内联函数或内联变量(C++17 起) 可以在包含在多个源文件中的头文件中定义。

笔记

如果具有外部链接的内联函数或变量(C++17 起)在不同的翻译单元中定义不同,则程序格式错误,无需诊断。

(强调我的)

由于您提供的定义不相同,因此该程序是 IFNDR。