我有一个共享库,它导出一个函数,该函数从全局变量返回一个字符串,如下所示:
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;
}
答案 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_name
和test_get_another_name
,这样您就可以比较这两个函数生成的代码。