簡體   English   中英

將 atomic<> 定義為函數內的靜態變量

[英]Defining an atomic<> as a static variable inside a function

C++11 要求函數內的靜態變量在函數的第一次運行時進行原子初始化。 有效地做到這一點的唯一方法是雙重檢查鎖定,以始終防止昂貴的互斥鎖。
我只是有必要在函數內部有一個靜態 atomic<size_t> 。 如果這樣的原子通過雙重檢查鎖定以原子方式初始化,那將沒有意義。 相反,它應該像另一個靜態初始化的非常量本機變量一樣處理。
我在 Windows 下使用 VC++ 和 Intel C++ 以及在 Linux 下使用 clang++ 和 g++ 檢查了生成的代碼,所有生成的代碼都符合我的預期。 但這真的是可靠的,並且是標准規定的,原子應該獨立於其他對象來處理嗎?

std::atomic的默認構造函數是constexpr ,盡管在 C++20 之前這是因為它很簡單而且對象還不能使用。 這意味着不需要動態初始化,正如標准所說的那樣,這是有效的。

Davis Herring 大部分是正確的,這是因為數據類型是一個微不足道的數據類型,編譯器可以檢查它的初始化沒有任何副作用(實際上不需要 constexpr 構造)。 我使用以下代碼進行了檢查:

#include <iostream>

using namespace std;

struct S
{
    S( int i ) : i( i ) {}
    operator int() { return i; }
    ~S() {}
private:
    int i;
};

S &f();

int main()
{
    cout << f() << endl;
}

#if defined(_MSC_VER)
__declspec(noinline)
#elif defined(__llvm__) || defined(__GNUC__)
__attribute((noinline))
#endif
S &f()
{
    static S s( 123 );
    return s;
}

上面的代碼生成通常的雙重檢查鎖定初始化。 如果您注釋掉 S 的析構函數,則 f() 中的代碼僅返回對可修改內存中靜態初始化數據的引用。

暫無
暫無

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

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