[英]Using a global variable to initialize other global variable in different compilation units
我有一個共享庫,該庫可以導出一個從全局變量返回字符串的函數,如下所示:
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;
}
據我了解,這應該是未定義的行為,因為在創建struct對象時還不一定要初始化變量“ name”,對嗎? 如果是這樣,將“ name”變量移入“ test_get_name”內是否有效?:
const std::string &test_get_name()
{
static std::string name = "Test";
return name;
}
函數內部的靜態變量將在第一次調用該函數時進行初始化,因此可以使用。
對於除string
之外的其他事物(例如具有更多副作用的類),可能會有所不同,就好像未調用該函數一樣,該對象將永遠不會被構造。
您的第二種方法可以工作(第一種方法不安全),但是會花費您線程安全的初始化程序 。 這具有最小的運行時開銷,但確實生成了大量代碼, 請參見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
,因此可以比較這兩個函數生成的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.