函数局部静态 constexpr 变量

cpt*_*ssa 5 c++ constexpr c++17

这个问题(和代码)的灵感来自 Jason Turner 的《C++ Weekly》一集:停止使用constexpr(并使用此代替!)

假设下面的代码(编译器资源管理器

我的理解是,在声明函数局部变量时,static constexpr我保证该变量仅初始化一次(静态),并且如果编译器无法证明单线程访问(由于它是 constexpr),通常不需要任何线程安全开销。

但是c++标准能保证这一点吗?标准中是否有任何地方可以确保我该行static constexpr auto arr = getArr();永远不会导致编译器添加互斥体或其他类型的线程保护?

Jason Turner 的剧集或这个 stackoverflow 问题都没有提到局部静态变量可能带来的线程安全开销,这就是我正在寻找明确答案的要点 - 最好通过指向标准。

所以需要明确的是:我可以确保arr函数getVal()在编译时初始化,而不需要任何线程同步吗?

constexpr auto getArr()
{
    std::array<int,10> arr;
    for (int i = 0; i < 10; ++i) {
        arr[i] = i*2;
    } 
    return arr;
}

auto getVal(int i)
{
    static constexpr auto arr = getArr();
    return arr[i] + 1;
}

int main()
{
    return getVal(4);
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*uch 1

由于初始化发生在编译时,因此运行时不需要同步机制。static对此没有影响。它只是使值可以直接在数据内存段中访问。如果没有,static则必须首先将值从那里复制到堆栈。

您不会在标准中找到不提供同步机制的保证。实现者可以自由添加额外的代码和检查,只要他们不改变代码的含义即可。但没有实现者会添加这样的机制,因为它没有任何好处。