簡體   English   中英

使用全局變量在不同的編譯單元中初始化其他全局變量

[英]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_nametest_get_another_name ,因此可以比較這兩個函數生成的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM