C++ 使用全局变量在不同的编译单元中初始化其他全局变量

C++ 使用全局变量在不同的编译单元中初始化其他全局变量,c++,global-variables,compilationunit,C++,Global Variables,Compilationunit,我有一个共享库,它导出一个函数,该函数从全局变量返回字符串,如下所示: 测试h: const std::string &test_get_name(); test.cpp: static std::string name = "Test"; const std::string &test_get_name() {return name;} 在我的主程序(链接到共享库)中,我定义了一个全局变量(如果它是静态的,是否仍称为“全局”变量?),它使用该函数初始化对象: main.cp

我有一个共享库,它导出一个函数,该函数从全局变量返回字符串,如下所示:

测试h:

const std::string &test_get_name();
test.cpp:

static std::string name = "Test";
const std::string &test_get_name() {return name;}
在我的主程序(链接到共享库)中,我定义了一个全局变量(如果它是静态的,是否仍称为“全局”变量?),它使用该函数初始化对象:

main.cpp:

#include "test.h"
#include <iostream>
struct TestStruct
{
    std::string value;
};
static TestStruct v{test_get_name()};

int main(int argc,char *argv[])
{
    std::cout<<v.value<<std::endl;
    return 0;
}

函数中的静态变量将在第一次调用函数时初始化,因此它将正常工作


对于除
字符串
以外的事物,例如具有更多副作用的类,可能存在差异,因为如果不调用函数,则永远不会构造对象。

函数中的静态变量将在第一次调用函数时初始化,因此是的,它将工作


除了
字符串
之外的东西,比如一个具有更多副作用的类,可能会有不同,因为如果不调用函数,则永远不会构造对象。

您的第二种方法会起作用(第一种方法不安全),但它会花费您大量的时间。这具有最小的运行时开销,但它确实会生成大量代码

如果这让您感到困扰,那么这个函数生成的代码似乎并不太糟糕(gcc和clang都构建了临时内联):

然后当然,
static TestStruct v{test_get_另一个_name()}是安全的


您可以在上面的Godbolt链接中找到
test\u get\u name
test\u get\u other\u name
,这样您就可以比较这两个函数生成的代码了。

您的第二种方法可以工作(第一种方法不安全),但它会花费您大量的时间。这具有最小的运行时开销,但它确实会生成大量代码

如果这让您感到困扰,那么这个函数生成的代码似乎并不太糟糕(gcc和clang都构建了临时内联):

然后当然,
static TestStruct v{test_get_另一个_name()}是安全的


您可以在上面的Godbolt链接中找到
test\u-get\u-name
test\u-get\u-an\u-name
,以便比较这两个函数生成的代码。

此构造的更好名称是单例。此构造的更好名称是单例。
const std::string &test_get_name()
{
    static std::string name = "Test";
    return name;
}
const std::string test_get_another_name()
{
    return "Test 2";
}