【问题标题】:Why C++20 doesn't support out-of-order designated initializer?为什么 C++20 不支持乱序指定初始化器?
【发布时间】:2019-04-14 11:36:09
【问题描述】:

在阅读C++ reference 时,我对这一段有疑问:

注意:乱序指定初始化,嵌套指定 初始化,指定初始化器和常规的混合 初始化器和数组的指定初始化都是 在 C 编程语言中支持,但在 C++ 中不允许。

是否有任何技术原因阻止 C++ 支持乱序指定初始化?

【问题讨论】:

  • 可能是因为上面提到的东西在C语言中一直有点安全隐患。

标签: c++ c++20 designated-initializer


【解决方案1】:

是的,基本原理在附录 C(资料性)中介绍 兼容性 特别是[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 表达式语法冲突。 很少使用嵌套指示符。

first revision of the proposal 也讨论了这个话题:

为了满足这些保证复制省略的期望,我们要求出现的指示符 作为数据成员声明序列的子序列,以便求值顺序 匹配声明顺序,在指定初始化中也是从左到右的

您可以获取最新版本here

【讨论】:

  • 如果指定为:初始化顺序将与成员顺序相同,我认为没有问题。它之前已经发生在 init list 上。如果允许这样做会不会产生负面影响?
  • @GermánDiago,我猜他们认为它(允许成员初始化列表中的任意顺序)是一个糟糕的设计决定,并且不想进一步传播它:毕竟,希望大多数程序员永远不会违反该顺序无论如何,感谢-Wall
【解决方案2】:

只有一小部分来自 C 的指定初始化选项是痛苦的。也许将来会被纠正。目前,一些编译器没有 C++20 标准那么严格。这个sn-p:

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

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

【讨论】:

    猜你喜欢
    • 2020-03-11
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2015-01-18
    相关资源
    最近更新 更多