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

时间:2018-06-05 07:20:15

标签: c++ global-variables compilationunit

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

test.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;
}

据我了解,这应该是未定义的行为,因为变量'name'在创建struct对象时尚未初始化,这是正确的吗?如果是这样,如果我在“test_get_name”中移动'name'变量,它是否有效?:

const std::string &test_get_name()
{
    static std::string name = "Test";
    return name;
}

2 个答案:

答案 0 :(得分:1)

函数内部的静态变量将在第一次调用函数时初始化,所以是的,它会起作用。

对于string以外的其他东西,就像具有更多副作用的类一样,可能存在差异,就好像未调用该函数一样,该对象永远不会被构造。

答案 1 :(得分:1)

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

如果这困扰你,这个函数生成的代码似乎不太糟糕(gcc和clang构造临时内联):

const std::string test_get_another_name()
{
    return "Test 2";
}

当然,static TestStruct v{test_get_another_name()};是安全的。

您可以在上面的Godbolt链接中找到test_get_nametest_get_another_name,这样您就可以比较这两个函数生成的代码。