当我汇总初始化数组而gcc没有时,Clang警告我 [英] Clang warns me when I aggregate initialize an array while gcc doesn't

查看:1167
本文介绍了当我汇总初始化数组而gcc没有时,Clang警告我的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用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>()); (auto&& i:c)std :: cout<<<我<< ;
std :: cout<<的std :: ENDL;
}

发出以下命令:


clang ++ -std = c ++ 14 -O2 -Wall -pedantic -pthread main.cpp


它发出警告:


警告:在子对象初始化
[-Wmissing-braces]


CLANG DEMO 然而,海湾合作委员会编写了这个程序,警告。



GCC DEMO



Q:





  1. Clangs警告我的原因是什么?
  2. 在某些情况下,大括号可以被忽略。这是其中的一种情况。用于初始化 a b 的最外括号是可选的。无论哪种方式,它在语法上都是正确的 - 但只是包含它们就更清楚了。 Clang只是警告你(警告,而不是错误) - 这是一个完全有效的警告。正如 chris 指出,使用 -Wmissing-braces ,gcc发出相同的警告。最终,两个编译器都接受代码,这是正确的;毕竟,这是一个有效的程序。这就是关键所在。



    从[dcl.init.aggr]:


    大括号可以省略在初始化列表中,如下所示。如果 initializer-list 以左大括号开头,则
    后续的逗号分隔 初始化子句列表将初始化成员的一个子集;与成员相比,存在更多的初始化子句
    错误。但是,如果子集合
    initializer-list 不以左大括号开头,则列表中只有足够的初始化子集会被带到
    初始化子集的成员;任何剩余的初始化子句 剩下来初始化当前子集合所属的集合的下一个
    成员。

      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 进行初始化。在以下示例中,初始化程序列表中的花括号被省略;但是 initializer-list
    与上例中的完全支撑的 initializer-list 具有相同的效果,

      float y [4] [3] = {
    1,3,5,2,4,6,3,5,7
    } ;

    y 的初始值设定项从左开始大括号,但是 y [0] 不是,所以使用了
    列表中的三个元素。同样地,接下来的三个也被连续地用于 y [1] y [2] - 结束示例]



    When I compile the following piece of code with 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;
    }
    

    by issuing the command:

    clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp

    It issues the warning:

    warning: suggest braces around initialization of subobject [-Wmissing-braces]

    CLANG DEMO

    However, GCC compiles this program with out issuing a warning at all.

    GCC DEMO

    Q:

    1. Which compiler is right?
    2. What's the reason that Clangs warns me?

    解决方案

    In some cases, braces can be elided. This is one of those cases. The outer-most braces for initializing a and b are optional. It is syntactically correct either way - but it's clearer to just include them. Clang is just warning you (warning, not error) about this - it's a perfectly valid warning. And as chris, points out, with -Wmissing-braces, gcc issues the same warning. Ultimately, both compilers accept the code, which is correct; it is, after all, a valid program. That's all that matters.

    From [dcl.init.aggr]:

    Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. [ Example:

    float y[4][3] = {
        { 1, 3, 5 },
        { 2, 4, 6 },
        { 3, 5, 7 },
    };
    

    is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array y[0], namely y[0][0], y[0][1], and y[0][2]. Likewise the next two lines initialize y[1] and y[2]. The initializer ends early and therefore y[3]s elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,

    float y[4][3] = {
        1, 3, 5, 2, 4, 6, 3, 5, 7
    };
    

    The initializer for y begins with a left brace, but the one for y[0] does not, therefore three elements from the list are used. Likewise the next three are taken successively for y[1] and y[2]. —end example ]

    这篇关于当我汇总初始化数组而gcc没有时,Clang警告我的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆