为什么C++20不支持无序指定初始化器?

33
当我阅读C++参考时,对于这段话我有一个问题:
注意:在C编程语言中,支持无序指定初始化、嵌套指定初始化、混合指定初始化器和常规初始化器以及数组的指定初始化,但在C ++中不允许。
是否有任何技术原因阻止C ++支持无序指定初始化?

可能是因为在C语言中,这些事情一直都有一定的安全隐患。 - Lundin
2个回答

28

是的,理据在Annex C (informative)Compatibility中有所涉及,具体可见[diff.dcl]p10。(注意:这里的强调为作者加入):

受影响的子条款:[dcl.init.aggr]更改:与C语言相比,C++中指定初始化的支持受到限制。 在C++中,非静态数据成员的指定符必须按声明顺序指定,不支持数组元素和嵌套指定符,而且不能在同一初始化器列表中混合指定和非指定的初始化器。 例如:

struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2};  // valid C, invalid C++
int arr[3] = {[1] = 5};         // valid C, invalid C++
struct B b = {.a.x = 0};        // valid C, invalid C++
struct A c = {.x = 1, 2};       // valid C, invalid C++

原因:C++中,成员按照反向构造顺序销毁,并且初始化列表中的元素按照词法顺序评估,因此字段初始化程序必须按顺序指定。 数组设计符与lambda表达式语法冲突。 嵌套设计符很少使用。

提案的第一个修订版也讨论了这个主题:

为了满足这些对于保证复制省略的期望,我们要求设计符出现在数据成员声明序列的子序列中,以便评估顺序匹配声明顺序,并且在指定初始化中也是文本左到右的。

您可以在这里获取最新版本。


2
我最近也在Twitter上进行了一项调查。链接 - Shafik Yaghmour
8
如果明确规定初始化顺序与成员变量的顺序相同,我认为这并不会带来问题。在初始化列表中已经存在这种情况了。如果允许这样做,是否会产生任何负面影响? - Germán Diago
1
@GermánDiago,我猜他们认为(在成员初始化列表中允许任意顺序)是一个糟糕的设计决定,并且不想进一步传播它:毕竟,希望大多数程序员从未违反那个顺序,这要归功于 -Wall - GreenScape
他们应该允许大多数/全部+需要警告。特别是在已经被接受的更大问题的阴影下(比如不可能繁琐的初始化规则,包括在某些情况下合法化未初始化数据,而在其他情况下则不是,并且甚至用“默认初始化”这个委婉词语来掩饰它——真是太搞笑了... :)) - Sz.

7

只有 C 中的一小部分指定初始化选项是痛苦的。或许将来会得到纠正。目前,一些编译器对 C++20 标准不太严格。以下代码片段:

struct A {int x, y;};
A a = {.y=2, .x=4};

编译时会出现警告,但在clang-10.0.0及更高版本下运行良好(请参见https://godbolt.org/z/Ybnzz5chx)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接