gpt4 book ai didi

c++ - 何时以及如何默认初始化一个 const 变量?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:34:09 27 4
gpt4 key购买 nike

clang++ 不允许 default initialization of a const variable of class-type without a user-defined constructor ; g++ 的限制稍微少一些(见下文)。根据this answer ,这是因为 POD 类型“默认情况下未初始化”。如果我理解正确的话,这意味着默认初始化不会调用默认构造函数,也不会调用值初始化,因此 POD 类型中的数据成员不会被初始化。当然,其中包含未初始化值的 const POD 类型是没有意义的,因为它们永远不会被初始化,因此使用起来不安全。

这种情况有几种变体:

  1. 技术上该类型是“POD”,但不包含数据成员(仅包含函数)。 (clang++ 没有将此视为特例,我认为标准也没有,但 g++ 确实允许这样做,即使构造函数被标记为 explicit .)
  2. 使用 {} 定义了一个空构造函数。 (这是描述该问题的 clang 页面上推荐的解决方法。)
  3. 默认构造函数声明为=default。 (C++11 及更高版本;该类型仍被视为 POD,因此编译器和标准均未将其视为特例。)
  4. 聚合初始化是使用 {} 显式调用的,这(如果我理解正确的话)变成了值初始化。 (从 C++11 开始;两个编译器——我认为是标准——都允许这样做。)

在第一种情况下,不能有未初始化成员,因此不清楚为什么类本身的任何实例化都会被视为“未初始化”,无论它是否是 const 。由于 g++ 允许这种行为,使用它安全吗?为什么它被clang++和标准禁止? (是否还有其他情况,g++ 允许 POD 默认初始化,而 clang++ 不允许?)

在第二种和第三种情况下,使用 {} 而不是 =default 的要求对我来说似乎很奇怪。 编辑: this question很好地解释了差异,因此我删除了问题中询问差异的部分。 (不过,我仍然认为这是该语言的一个非常令人困惑的方面。)

最后,如果 Foo::Foo(void){}Foo f{} 是否总是对内置类型的成员进行零初始化code>、=default 还是隐式声明?

最佳答案

Since g++ allows this behavior, is it safe to use?

什么意义上的安全?目前显然不可移植。但是,它不会在 g++ 上给您带来意想不到的结果。

Why is it prohibited by clang++ and the standard?

大概是委员会在将“需要用户提供的构造函数”规则放入 C++98 时没有考虑到这一点,或者认为特殊外壳的空 POD 类不值得规范的复杂性; clang++ 只是遵循标准。但是,标准是 likely going to change更普遍地允许您编写 const Foo f; 只要构造函数实际上会初始化每个子对象。

Finally, will Foo f{}; always zero-initialize members of built-in type if Foo::Foo(void) is {}, =default, or implicitly-declared?

后两者是的。不,首先。这算作用户提供,因此值初始化在调用默认构造函数之前不会执行零初始化。

关于c++ - 何时以及如何默认初始化一个 const 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30657867/

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