gpt4 book ai didi

c++ - 在C++中,内置类型的简单初始化是否不受静态初始化顺序的影响?

转载 作者:行者123 更新时间:2023-12-02 10:08:39 24 4
gpt4 key购买 nike

我知道C++中的static initialization order fiasco
construct on first use idiom避免它。因此在下面的代码中a的全局分配可能早于foo::a的全局分配,因此a的值未定义。另一方面,全局
分配b是可以的,因为它调用了foo::b()函数。

#include <iostream>
#include <string>

using namespace std;

// foo.hpp

class foo {
public:
static const string a;
static const string& b();
static const char* const c;
static const char* const d[2];
static const int e;
static const int f[2];
};

// foo.cpp

const string foo::a("astr");
const string& foo::b() {
static const string t("bstr");
return t;
}
const char* const foo::c = "cstr";
const char* const foo::d[2] = {"dstr1", "dstr2"};
const int foo::e = 5;
const int foo::f[2] = {6, 7};

// main.cpp

// global initializations
string a = foo::a; // dangerous, might be "" or "astr"
string b = foo::b(); // safe, guaranteed to be "bstr"
const char* c = foo::c; // what about these...?
const char* d = foo::d[0];
int e = foo::e;
int f = foo::f[0];

int main() {
cout << a << " " << b << "\n"
<< c << " " << d << "\n"
<< e << " " << f << "\n";
}

(想象一下,我在这里结合了 foo.hppfoo.cppmain.cpp。)
但是,内置类型或它们的数组的变量又如何呢?
因此,此代码中 cdef的全局分配安全吗?
链接器似乎可以为这些变量设置内存
因此在运行时不需要初始化。但是我可以依靠
这个?

我知道我不应该使用全局变量。但是,我是作者
一个库(foo.cpp和foo.hpp),我无法控制什么
我图书馆的用户(main.cpp的作者)这样做。

最佳答案

这里的关键是“static初始化”(使用标准语言正式称为具有静态存储持续时间,具有顺序失败的对象的动态初始化)与静态初始化之间的区别。
该标准说([basic.start.static]节)

A constant initializer for an object o is an expression that is a constant expression, except that it may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types. [ Note: Such a class may have a non-trivial destructor — end note ]

Constant initialization is performed:

  • if each full-expression (including implicit conversions) that appears in the initializer of a reference with static or thread storage duration is a constant expression and the reference is bound to a glvalue designating an object with static storage duration, to a temporary object or subobject thereof, or to a function;
  • if an object with static or thread storage duration is initialized by a constructor call, and if the initialization full-expression is a constant initializer for the object;
  • if an object with static or thread storage duration is not initialized by a constructor call and if either the object is value-initialized or every full-expression that appears in its initializer is a constant expression.

If constant initialization is not performed, a variable with static storage duration or thread storage duration is zero-initialized. Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.


您的 cdef对象具有常量初始化程序,因此它们的初始化在静态初始化阶段完成(即使 cd本身不是常量),并且它们的值在所有动态初始化期间都可用,即使后来出现在词法上

关于c++ - 在C++中,内置类型的简单初始化是否不受静态初始化顺序的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44232434/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com