具有 char 数组的 C++ 结构以不寻常的方式初始化为零
Posted
技术标签:
【中文标题】具有 char 数组的 C++ 结构以不寻常的方式初始化为零【英文标题】:C++ struct with char arrays initialize to zero in unusual way 【发布时间】:2018-10-04 04:34:58 【问题描述】:遇到了一段不常见的 c++ 初始化代码,似乎可以与以下代码一起正常工作...
struct sfoobar char bar[10]; char foo[10]; ;
...
sfoobar x 0 ;
这是将这些 char 数组初始化为零的可接受方法吗?
【问题讨论】:
不常见其实很常见。 是的,这是一种可以接受的方式。sfoobar x ;
将是首选模式,因为即使0
不是第一个成员的正确初始化程序,它仍然有效。与 struct qux std::string bar; char foo[10]; ;
比较,则 qux x0;
会导致未定义的行为
@M.M 您能否详细说明为什么qux x0;
会导致 UB?为什么这不会简单地产生编译错误呢? (如果std::string
不支持这样的初始化。)
@303 std::string
有一个构造函数采用char const *
(如果传递了空指针,则为UB),0
可以隐式转换为空指针
【参考方案1】:
这在 C++ 中有效。因为sfoobar x 0 ;
的效果会将x.bar
和x.foo
的所有元素初始化为0
。
根据aggregate initialization的规则,嵌套初始化列表的大括号可以省略,
嵌套初始化器列表周围的大括号可以省略(省略),在这种情况下,使用尽可能多的初始化器子句来初始化相应子聚合的每个成员或元素,随后的初始化器子句用于初始化以下对象的成员。
那么sfoobar x 0 ;
表示将x.bar
的第一个元素初始化为0
,并且
如果初始化子句的数量小于成员
and bases (since C++17)
的数量或初始化列表完全为空,则其余成员and bases (since C++17)
由空列表初始化by their default initializers, if provided in the class definition, and otherwise (since C++14)
,按照通常的列表初始化规则(它使用默认构造函数对非类类型和非聚合类执行值初始化,并为聚合执行聚合初始化)。
因此,所有剩余的元素,包括x.bar
的第 2 到第 10 个元素以及 x.foo
的所有元素也将值初始化为 0
。
【讨论】:
问题,value initialization
和 zero initialization
对于 char 数组是否相同?
@codekaizer 是的,对于非类类型value initialization 导致zero initialization。对于这种情况,流程将是对char
数组进行聚合初始化,然后对元素(即char
s)进行值初始化,然后进行零初始化 关于元素(即char
s)。
那么如果我改写sfoobar x 1 ;
,那么x.bar
的第一个元素被初始化为1,而x.bar
的所有其他元素和x.foo
的所有元素都被初始化为零?而如果我只写sfoobar x
,那么x.bar
和x.foo
的元素的值是不确定的?
@M.Winter 是的,没错。以上是关于具有 char 数组的 C++ 结构以不寻常的方式初始化为零的主要内容,如果未能解决你的问题,请参考以下文章