常量与非常量内联变量

问题描述 投票:1回答:1

假设我有以下两个文件:

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

这里到底发生了什么?

c++ c++17 inline linkage
1个回答
0
投票

由于您给出的原因,您的程序具有不确定的行为。

不需要您的工具链来诊断不确定的行为,并且在通常难以“发现”的情况下(很多情况下,它也不会打扰)。最好的情况是,链接程序(not编译器)可以在构建过程中发现此特殊情况,如果编写它的人认为这样做足够有用,可以保证额外的工作和构建时间。

但是,不:此规则属于程序员的责任。您违反了规则,现在您的程序已经以复杂的方式被破坏,我们可能可以利用有关您的计算机,工具链,月相,心情,鞋子的颜色和程序的组装等足够的信息来进行工作……但这并不是真的值。

添加const可能导致编译器(链接器)在某些地方省略了对该变量的“引用”,从而在使用时从字面上“内联”了初始化值,以达到最佳化的目的。当它知道值不会从初始化更改时就可以这样做(感谢const)。结果是您不再从未定义的行为中观察到太多的怪异现象,因为您从程序中看到的行为更受制于各个翻译单元。

© www.soinside.com 2019 - 2024. All rights reserved.