假设我有以下两个文件:
test.cpp
inline double pi { 3.1415 };
#include <iostream>
void test() {
std::cout << pi << std::endl;
}
和
main.cpp
inline double pi { 2.178 };
void test();
#include <iostream>
int main() {
std::cout << pi << std::endl;
test();
}
inline
变量默认情况下具有外部链接。因此,根据一个定义规则(ODR),我最初的想法是,只要在变量中内联声明并且包含相同精确定义
所以,我的第一个问题是,即使变量是内联声明的,但它们在翻译单元之间具有不同的定义,为什么还要编译该程序?
第二,内联非常量和内联const变量有什么区别?
例如,如果您运行上面的代码,您将获得以下输出
2.1782.178
但是,如果您同时访问两个文件并将pi
设为const double
,即inline const double pi {3.1415}
和inline const double pi {2.178}
您将获得以下输出:
2.1783.1415
这里到底发生了什么?
由于您给出的原因,您的程序具有不确定的行为。
不需要您的工具链来诊断不确定的行为,并且在通常难以“发现”的情况下(很多情况下,它也不会打扰)。最好的情况是,链接程序(not编译器)可以在构建过程中发现此特殊情况,如果编写它的人认为这样做足够有用,可以保证额外的工作和构建时间。
但是,不:此规则属于程序员的责任。您违反了规则,现在您的程序已经以复杂的方式被破坏,我们可能可以利用有关您的计算机,工具链,月相,心情,鞋子的颜色和程序的组装等足够的信息来进行工作……但这并不是真的值。
添加const
可能导致编译器(链接器)在某些地方省略了对该变量的“引用”,从而在使用时从字面上“内联”了初始化值,以达到最佳化的目的。当它知道值不会从初始化更改时就可以这样做(感谢const
)。结果是您不再从未定义的行为中观察到太多的怪异现象,因为您从程序中看到的行为更受制于各个翻译单元。