为什么不内联变量?

xiv*_*r77 12 c++ inline language-lawyer

inlineC++中的关键字允许在头文件中定义函数,以便编译器可以实际内联它们或只保留函数的一个副本.这允许通过直接在头文件中定义函数来减少编译单元的数量,其优点通常是编译时间快几倍,并且执行速度可能更快.

为什么这个相同的模式不能应用于命名空间范围变量,而C++中的函数在将它们视为特殊指针时实际上是命名空间范围变量?

我能想到的是使用内联函数的静态局部变量.

inline std::string& Hello__() { //Edit: Added the &
    static std::string hello("Hello");
    return hello;
}

#define Hello (Hello__())
Run Code Online (Sandbox Code Playgroud)

编辑:我想澄清我的问题如下.

我正在使用术语'inline'作为编译器理解的内容.它允许具有相同名称的相同定义在多个编译单元中,允许标题中的定义."内联"的主要优点不是宏功能所具有的性能优势,而是编译单元数量减少所需的编译时间更短.它可能会短几倍.

我确实提出了一个解决方案,让变量像内联函数一样工作.但我仍然在寻找更好的方法来做到这一点.

为了清楚地说明,我想要实现的是在标题中定义名称空间范围变量,就像内联函数一样,以便使构建过程尽可能简单快速.


EDIT2:谢谢你的链接通过DYP评论.我刚读过这个提案,这正是我的想法.该提案的现状如何?

引自该提案:

然而,希望存在全局唯一对象而不必选择用于定义它的单个翻译单元并不罕见.实际上,做出这种选择通常需要使用非平凡的预处理器宏,单独编译的库或两者.但是,C++的一个优势是它支持headeronly库开发的能力.在这种情况下,缺乏定义内联变量的能力对库设计造成了重大限制.

gnz*_*lbg 16

C++ 17有inline variables,见:N4424.


Uri*_*her 2

这是我根据你的建议做了一个简短的实验:

文件a.cpp:

inline int& get_inline_int() {
    static int my_inline_int = 0;
    return my_inline_int;
}

void set_me(int x) {
    get_inline_int() = x;
}
Run Code Online (Sandbox Code Playgroud)

文件b.cpp:

#include <iostream>

inline int& get_inline_int() {
    static int my_inline_int = 0;
    return my_inline_int += 2;
}

void show_me() {
    std::cout << get_inline_int() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

文件main.cpp:

void set_me(int);
void show_me();

int main() {
    set_me(7);
    show_me();
    set_me(8);
    show_me();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我做了一点作弊,为同一个函数提供了两种不同的实现。如果没有内联,链接器会抱怨重复的符号,但我在使用内联时就摆脱了它。

我不得不承认这个结果让我感到惊讶。我尝试了 g++ 和 clang++ 并得到了类似的结果:

clang++ a.cpp b.cpp main.cpp -o runme
Run Code Online (Sandbox Code Playgroud)

将输出

7
8

clang++ b.cpp a.cpp main.cpp -o runme
Run Code Online (Sandbox Code Playgroud)

将输出

9
10
Run Code Online (Sandbox Code Playgroud)

因此,我认为这是对语言的滥用,因为编译结果是不可预测的,并且通常不是您想要的结果。如果委员会能够定义可预测的行为,我会自己使用这些所谓的“内联”变量。