当我聚合初始化数组而 gcc 没有时,Clang 警告我
Clang warns me when I aggregate initialize an array while gcc doesn't
当我用CLANG编译以下代码时:
#include <iostream>
#include <array>
#include <algorithm>
#include <functional>
int main() {
std::array<int, 2> a = {1, 2};
std::array<int, 2> b = {2, 1};
std::array<int, 2> c;
std::transform(a.begin(), a.end(), b.begin(), c.begin(), std::multiplies<int>());
for(auto &&i : c) std::cout << i << " ";
std::cout << std::endl;
}
通过发出命令:
clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
它发出警告:
警告:建议在子对象初始化周围使用大括号 [-缺少大括号]
叮当演示
但是,GCC编译此程序时根本没有发出警告。
海湾合作委员会演示
问:
- 哪个编译器是正确的? 叮
- 叮当当警告我的原因是什么?
在某些情况下,可以省略大括号。这是其中一种情况。用于初始化a
和b
的最外大括号是可选的。无论哪种方式,它在语法上都是正确的 - 但只包含它们更清楚。Clang只是警告你(警告,而不是错误(- 这是一个完全有效的警告。正如克里斯指出的那样,-Wmissing-braces
,gcc发出了同样的警告。最终,两个编译器都接受代码,这是正确的;毕竟,这是一个有效的程序。这才是最重要的。
来自 [dcl.init.aggr]:
可以在初始值设定项列表中省略大括号,如下所示。如果初始值设定项列表以左大括号开头,则 后面的逗号分隔的初始值设定项子句列表初始化子聚合的成员;是的 错误的初始值设定项子句多于成员。但是,如果子聚合的初始值设定项列表 不以左大括号开头,则仅从列表中获取足够的初始值设定项子句 初始化子聚合的成员;任何剩余的初始值设定项子句都留给初始化下一个 当前子聚合是其成员的聚合的成员。[ 示例:
float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };
是一个完全支撑的初始化:
1
、3
和5
初始化数组y[0]
的第一行,即y[0][0]
,y[0][1]
,y[0][2]
。同样,接下来的两行初始化y[1]
和y[2]
。初始值设定项提前结束,并且 因此y[3]
s 元素被初始化,就像使用形式为float()
的表达式显式初始化一样, 也就是说,用0.0
初始化。在下面的示例中,省略了初始值设定项列表中的大括号;然而 初始值设定项列表与上述示例中的完全支撑的初始值设定项列表具有相同的效果,float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
y
的初始值设定项以左大括号开头,但
y[0]
的初始值设定项不以左大括号开头,因此三个元素来自 使用列表。同样,接下来的三个依次用于y[1]
和y[2]
。—结束示例 ]
哪个编译器是正确的?
两个编译器都是正确的。大括号消除是一种允许聚合由一对大括号初始化的功能。每个成员 suboject 都根据需要使用任意数量的初始值设定项子句进行初始化。这是为了允许更方便的初始化形式。
叮叮当当警告我的原因是什么?
Clang通过警告你很有帮助,因为虽然你能够省略大括号,但如果你不小心,并不总是清楚聚合将如何初始化。您必须确定哪些初始值设定项子句与哪些成员子对象有关。
- Clang 给了我符号更改的警告,但代码仍然产生正确的输出
- 当 noexcept 函数尝试在 gcc 或 clang 中调用非 noexcept 函数时启用警告
- 在 C++11 中轻松初始化模板类的静态成员,没有 clang 警告
- Clang-CL 警告 strnicmp 已弃用,请使用 ISO C 并C++符合标准的名称_strnicmp
- 冲突的 CLANG"虚拟 dtor"和"已弃用的复制运算符"警告
- 有没有办法在初始化字符串时避免来自 clang-tidy(fuchsia-default-arguments)的警告?
- 为什么 gcc 和 clang 都没有发出任何警告?
- Clang:覆盖之前在命令行上指定的所有警告和错误警告标志
- 为什么 Clang 警告未使用的指针和未使用的基元,而不是未使用的对象?
- clang++ 8.0.1 自分配重载警告
- Clang 对使用的类型别名发出"unused type alias"警告
- 如果对象在同一层次结构中,-Wreturn-std-move clang 警告是否正确
- 关于静态模板化 constexpr 的 Clang 警告(未定义内联函数)
- 如何禁用"不支持优化标志"的 clang 警告
- 返回对函数参数的引用时没有 clang 警告
- 为什么 clang++ 警告内联enable_if然后无法链接
- 类模板的Makefile问题:clang警告链接器输入未使用
- 没有clang警告或错误,如果c++ 11 lambda返回错误的类型
- 当我聚合初始化数组而 gcc 没有时,Clang 警告我
- 使用makefile隐藏clang警告