何时以及如何默认初始化const变量?

Kyl*_*and 6 c++ constructor default-constructor c++11

clang++没有用户定义的构造函数,它不允许默认初始化类型的const变量 ; g++限制性稍差(见下文).根据这个答案,这是因为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对我来说似乎很奇怪.编辑: 这个问题很好地解释了差异,所以我已经删除了询问区别的部分问题.(尽管如此,我仍然认为这是一种非常令人困惑的语言方面.)

最后,将Foo f{}始终是零初始化内置类型的成员如果Foo::Foo(void){},=default或隐式声明的?

T.C*_*.C. 5

由于g ++允许这种行为,使用它是否安全?

安全在什么意义上?目前显然不便携.但是,它不会给你带来意想不到的g ++结果.

为什么clang ++和标准禁止它?

据推测,当委员会在C++ 98中提出"用户提供的构造函数"规则时,或者没有考虑它,或者认为特殊套管空POD类不值得规范复杂性; clang ++只是遵循标准.但是,标准可能会更改为更普遍地允许您编写const Foo f;,只要构造函数实际上将初始化每个子对象.

最后,将Foo f{};始终是零初始化内置类型的成员如果Foo::Foo(void){},=default或隐式声明的?

对于后两者是肯定的.不是第一个.那个计为用户提供的,因此值初始化在调用默认构造函数之前不会执行零初始化.