Phi*_*ßen 47 c++ compiler-warnings c++11
考虑以下程序:
#include <array>
int main()
{
std::array<int, 1> x = { 0 }; // warning!
x = { { 0 } }; // no warning
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一次初始化导致gcc 4.7.2上的警告......
main.cpp:5:22: warning: unused variable ‘x’ [-Wunused-variable]
Run Code Online (Sandbox Code Playgroud)
......和铿锵3.1
main.cpp:5:28: warning: suggest braces around initialization of subobject [-Wmissing-braces]
std::array<int, 1> x = { 0 };
Run Code Online (Sandbox Code Playgroud)
就标准而言,双花键或单花括号之间应该没有区别,至少在这个例子中.
有两种方法可以处理警告:
你有什么建议?恕我直言,双卷曲表达看起来有些难看.另一方面,警告可能会在更复杂的示例中检测到实际问题.你知道这个警告对你有帮助的例子吗?
小智 46
-Wmissing-braces
-Wall
由于您描述的原因,将不再在GCC (用于C++模式)中启用4.8版本.对于GCC的当前版本,要么禁用或忽略该警告,您所拥有的代码将按其应有的方式编写.
警告可能是为了涵盖诸如此类的代码
struct A { int a; int b; };
struct B { A a; int b; };
B b = {
1,
2 // initialises b.a.b, not b.b
};
Run Code Online (Sandbox Code Playgroud)
但是,恕我直言,已经处理得很好-Wmissing-field-initializers
,没有警告你的原始代码.
我在Xcode 6.1.1(截至2015年3月9日的当前版本)中收到相同的警告.当我在每个子对象周围添加额外的大括号时,我收到错误.当我在整个初始化列表周围添加一组额外的大括号时,警告就会消失.根据标准规范14882:2011 23.3.2.1 [array.overview]第2小节明确说明
array<T, N> a = { initializer-list };
Run Code Online (Sandbox Code Playgroud)
其中initializer-list是一个逗号分隔的列表,最多包含N个元素,其类型可转换为T.
Xcode 6.1.1(下面)中的代码结果
array<int, 2> key1 = {1, 2}; // warning: suggest braces around initialization of subobject
array<int, 2> key2 = { {1}, {2} }; // error: no viable overload =
array<int, 2> key3 = array<int, 2> { {1}, {2} }; // error: excess elements in struct initializer
array<int, 2> key4 = { {1, 2} }; // no warning and no error
Run Code Online (Sandbox Code Playgroud)
当我们查看14882:2011 8.5 [dcl.init]第1小节时,我们看到'initializer-list'可以选择包含'initializer-clause',它本身可以是'braced-init-list'.所以两种方式都应该是正确的.虽然基于规范我个人认为单个大括号不应该输出std :: array initializer-list的编译器警告,而双括号是过度的.
Clang 6.0 抑制了有关缺少大括号的警告。svn 日志显示:
当聚合初始化具有本身就是聚合的单个字段的结构时,抑制 -Wmissing-braces 警告。在 C++ 中,std::array 类型的这种初始化保证可以按照标准工作,完全符合惯用语,并且 Clang 的“建议”替代方案在技术上是无效的。
-Wmissing-braces
因此,如果需要支持,我会省略大括号并禁用6.0 之前的 Clang。