c++ - 从相同类型的静态成员进行类内初始化

标签 c++ initialization language-lawyer static-members in-class-initialization

下面的代码是否有效,例如不会带来未定义的行为?

struct S
{
    int i = s.i;
    static S s;
};

S S::s;

int main()
{
    S a;  // a.i = 0
    S::s.i = 42;
    S b;  // b.i = 42
}

据我所知,所有具有静态存储持续时间的变量都是零初始化的。因此 s.iS::s 创建时是 0,一切都很好。但也许我遗漏了什么。

最佳答案

我认为它定义明确。

[class.static.data]/6

Static data members are initialized and destroyed exactly like non-local variables.

[basic.start.static]/2 (emphasis mine)

A constant initializer for a variable or temporary object o is an initializer whose full-expression is a constant expression, except that if o is an object, such an initializer 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 a variable or temporary object with static or thread storage duration is initialized by a constant initializer for the entity. 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. All static initialization strongly happens before ([intro.races]) any dynamic initialization. [ Note: The dynamic initialization of non-local variables is described in [basic.start.dynamic]; that of local static variables is described in [stmt.dcl].  — end note ]

[dcl.init]/6 (emphasis mine)

To zero-initialize an object or reference of type T means:

  • if T is a scalar type, the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;
  • if T is a (possibly cv-qualified) non-union class type, each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized and padding is initialized to zero bits;
  • if T is a (possibly cv-qualified) union type, the object's first non-static named data member is zero-initialized and padding is initialized to zero bits;
  • if T is an array type, each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

因为 int i = s.i; 意味着 s.i 是动态初始化的,所以它保证事先是零初始化的。因此,当它稍后用于初始化自身时,它的值将不会不确定。预期为 0。

关于c++ - 从相同类型的静态成员进行类内初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51655331/

相关文章:

c++ - 字符串和字符串数组的零初始化(C++)

c++ - constexpr 模板参数怪异

c++ - RtlValidateHeap 问题

c++ - FILE* 和 ifstream 哪个有更好的内存使用率?

c++ - 将 header 包含到 OpenCL .cl 文件

Ruby 元编程 : Initialize singleton_class variable

java - 始终通过上下文在 Spring 服务中注入(inject)一些字段

c++ - 术语 `function declaration` 在 §7/9 (N4140) 中定义,但未定义为语法产生式。为什么?

union 成员的 C++ 生命周期

c++ - 尝试从本地类方法访问属性时出现编译错误