零初始化、静态初始化和值初始化有何不同?

Posted

技术标签:

【中文标题】零初始化、静态初始化和值初始化有何不同?【英文标题】:How Do Zero-Initialization, Static-Initialization, and Value-Initialization Differ? 【发布时间】:2016-06-09 16:54:45 【问题描述】:

Ben Voigt 指出here:

零初始化是静态初始化的步骤之一。但是你是对的,你不能盲目地替换后者(标签),因为值初始化也执行了零初始化。但是,在 C++ 的上下文中,不需要(一个名为的标签)零初始化,因为静态初始化和值初始化的标签已经存在,而且它们更相关。

我认为在某些情况下,"Zero-Initialize" 而不是 "Static-Initializing" 或 "Value-Initializing" 是有意义的,或者“零初始化”永远不会在野外发生,我应该使用更具体的术语,例如: “静态初始化”还是“值初始化”?

公平地说,我在这些主题上的大部分经验都来自研究this question 的答案,所以我确信 Ben Voigt 是对的,我希望有人能说明原因。

【问题讨论】:

似乎这个问题更多是针对 meta.SO 而不是 SO,因为它是关于标签的...... @Jarod42 我心中的问题是概念之一。我想我错过了 Ben Voigt 所说的,因为我不明白这些初始化之间的区别。我不确定我们如何才能了解元数据的技术性。 @Jarod 我不这么认为。这是一个元问题,因为 Jonathan 不是在问 C++,而是在问标准和专家用来谈论 C++ 的术语。但是 SO 仍然是正确的网站,meta.SO 仅针对有关 Stack Overflow 软件和政策的元问题的子集,而事实并非如此。 你可以说程序员是一个更好的家......但不是 meta.SO 零初始化是用户真正“询问”的其他一些初始化技术部分。 “复杂性”是针对那些初始化的。此外,零初始化也不会将这些初始化分组。 【参考方案1】:

零初始化可以自行发生;当使用比数组短的字符串字面量初始化字符数组时,剩余的字符被零初始化。但在所有其他情况下,零初始化发生在值初始化期间,或作为初始化具有静态或线程本地存储持续时间的对象的静态初始化步骤(这可以单独发生,也可以为动态初始化做准备)。

因此,除非您询问字符类型的零表示(而且我看不出该主题中有很多问题),否则其他标签之一 value-initialization 或 static-initialization 将适用,我可以'用完标签配额来申请zero-initialization 并没有多大价值。

【讨论】:

零初始化就行了,那么默认初始化呢? 我不知道为什么我们仍然有这个规则,因为更一般的“如果列表中的初始化子句少于聚合中的元素,那么每个元素都没有显式初始化应从其默认成员初始化程序(9.2)初始化,或者,如果没有默认成员初始化程序,则从空初始化程序列表(8.5.4)初始化。”已经保证了相同的行为,因为从空初始化器列表初始化字符类型是值初始化是零初始化。 @JonathanMee:不,这不是默认初始化,它可以调用用户构造函数。实际上有两个不同的类别。第一个是从 创建一个对象并且该类型的默认构造函数是微不足道的 a/k/a 值初始化时会发生什么(通常这不会发生在字符数组中,但我知道发生的事情之间没有实际区别那里以及所有其他元素比初始化器更多的聚合)。如果该类型确实具有用户定义的默认构造函数,则永远不会出现这种情况。 @JonathanMee:另一种情况是“静态初始化顺序惨败”的部分缓解。对于自动存储,对象在其初始化开始之前的值是一个不确定的值,并且检查它会导致未定义的行为(对于字符类型是缓慢的,对于所有其他类型是立即的)。但是静态存储持续时间的对象有时可以在初始化之前检查,值为零不是不确定的,即使对象类型确实具有默认构造函数,这也适用,因为尚未发生动态构造。 “准备静态初始化” - 你的意思是准备动态初始化。 “静态初始化”并不意味着“静态存储持续时间的对象的初始化”;它意味着别的东西。

以上是关于零初始化、静态初始化和值初始化有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

默认初始化和值初始化结构的不同性能

不可复制的对象和值初始化:g++ vs msvc

Java语言中,构造方法和一般方法有何不同

C++中,类内的成员变量自动初始化为零吗,而全局变量随意赋值

如何初始化一个静态数组?

静态代码块执行时机