这是GCC的错误吗?用工会初始化结构

时间:2014-02-05 13:50:40

标签: c++ gcc c++11 unions compiler-bug

我可能在GCC v4.8.2中发现了一个错误,但我想在提交之前先检查一下,因为这可能是我做错了!

以下代码:

#include <vector>
struct Message
{
  typedef union {
    char byte;
    const char *str;
  } Parameter;

  Parameter p1;
  Parameter p2;
};

int main()
{
  std::vector<Message> messages_;

  messages_.push_back({{ .byte = 'a' }});

  Message message = {{ .byte = 'a' }, { .str = "Hello World" }};
  messages_.push_back(message);

  messages_.push_back({{ .byte = 'a' }, { .str = "Hello World" }});
}

clang++ -std=c++11 main.cpp编译这个罚款。但是g++会输出:

main.cpp: In function ‘int main()’:
main.cpp:23:66: internal compiler error: in reshape_init_class, at cp/decl.c:5216
   messages_.push_back({{ .byte = 'a' }, { .str = "Hello World" }});
                                                                  ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccrf5vwr.out file, please attach this to your bugreport.

如果没有人有任何想法,我会将此作为错误提交,尽管根据我的经验,程序员问题几乎不是编译器错误,而且几乎总是他自己的错!

1 个答案:

答案 0 :(得分:3)

正如上面的评论中所回答的:你从GCC获得的包含短语internal compiler errorPlease submit a full bug report的任何错误消息肯定是编译器错误,而不是你自己的错!在这种情况下,该错误似乎与GCC在C ++模式下解析{{ ... }}有关,其中“...”包括指定的初始化程序。 @Sam已将其报告为GCC bug 59832

然而,正如@Angew指出的那样,这一行 -

messages_.push_back({{ .byte = 'a' }});

- 无效C ++。标准C ++不允许使用指定的初始化程序;这是C99中没有采用的C99特性(既不是C ++ 11也不是C ++ 14)。

至于为什么指定的初始值设定项在添加到C ++时存在问题,请参阅here,其中Doug Gregor询问编译器应如何解释

之类的内容
struct Foo {int x,y; };
void f(Foo);
void f(std::initializer_list<int>);

int main(){
    f({1});
    f({1,2});
    f({1,2,3});
    f({.x=1});
    f({.x=1,2});
    f({.x=1,2,3});
}

为了记录,GCC 4.8将所有六个视为f(initializer_list<int>)的来电。 Clang 3.5将前三个调用为f(initializer_list<int>),后两个调用f(Foo),最后一个调用为格式错误。基本上,它是一个非标准的构造:不同的编译器在他们的权利范围内以不同的方式对待它,他们确实