【问题标题】:Why is array initialization with brackets () marked as error by compilers?为什么带有括号 () 的数组初始化被编译器标记为错误?
【发布时间】:2021-04-02 10:00:32
【问题描述】:

我在研究 C++ 中的初始化语法,根据cppreference,有三种可能的写法,1) 括号,2) 等号,3) 大括号。

尝试使用 1) 括号语法初始化数组时,遇到错误。

int test() {
    int a[](1);

    return 0;
}

在 Compiler Explorer 上测试,我从 clang 11.0.0 获得

error: array initializer must be an initializer list
        int a[](1);
            ^

同样,使用 gcc 10.2 在同一个站点上

error: array must be initialized with a brace-enclosed initializer

现在,我知道如何使用大括号来初始化数组而不会出错。但这不是这个问题的重点。

我正在寻找 C++ 标准与此报告错误的对应关系。

我正在查看这个标准草案timsong-cpp(应该在 C++ 20 时间左右)。 第“(17.1)节 如果初始值设定项是(非带括号的)大括号初始化列表或 = 大括号初始化列表,...”谈论大括号列表 - 不是我们的情况。

然后有一段“(17.5) 否则,如果目标类型是数组,则对象初始化如下..."

我认为这应该涵盖我们的案例。它是关于数组的初始化,它也是一个“否则”部分,这意味着它不会谈论大括号列表。它可以讨论 1) 括号或 2) 等号,但从进一步的文本中我们看到它需要一个表达式列表:

"设 x1, ..., xk 为表达式列表的元素。"

当使用 1) 括号语法时,该表达式列表将在那里。作为旁注,“14 如果正在初始化的实体...”部分要求表达式列表在这种情况下只能是单个表达式。

根据标准措辞,声明 int a[](1); 应该将数组的长度设置为 1,并将其唯一元素初始化为值 1。但这在实现中不会发生。

该标准的哪些其他部分可以阻止这种解释?还是我还缺少其他东西?

【问题讨论】:

  • 如您所见godbolt.org/z/zcY3Mz,它适用于 g++10.2。可能 Clang 还没有实现它。
  • 所以我的错误是我忘记为 gcc 添加 -std=c++20。
  • 是的,带括号的聚合初始化是 C++20 的一项功能,您可以在 p0960r3 上阅读更多信息。 GCC10 支持 >

标签: c++ arrays language-lawyer standards initializer


【解决方案1】:

您尝试使用的功能是在 C++20 中添加的,称为“聚合的括号初始化”。从compiler support 页面可以看出,GCC 从 GCC10 开始支持此功能,而 Clang 尚不支持此功能。

【讨论】:

  • 感谢您指出它是一个新的 C++20 功能。我正在查看 C++20 标准,但认为它已经是一个较旧的功能。
猜你喜欢
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多