【问题标题】:Is this a GCC bug? Initializing structs with unions这是 GCC 错误吗?使用联合初始化结构
【发布时间】:2014-02-05 13:50:40
【问题描述】:

我可能在 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.

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

【问题讨论】:

  • Please submit a full bug report 已经是答案了
  • 内部编译器错误始终是编译器错误。
  • 从技术上讲,我认为这应该需要-std=g++11 进行编译,因为指定的初始化程序(或其他任何名称)是 C,而不是 C++。
  • 我觉得这和one that has already been reported是一样的bug,如果是这样,不需要重新报告。
  • 我已将它作为评论添加到那个:)

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


【解决方案1】:

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

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

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

— 是无效的 C++。标准 C++ 不允许指定的初始化程序;这是 C99 中未采用的 C++ 特性(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&lt;int&gt;) 的调用。 Clang 3.5 将前三个视为对f(initializer_list&lt;int&gt;) 的调用,后两个视为对f(Foo) 的调用,最后一个视为格式错误。基本上,这是一个非标准的构造:不同的编译器有权对其进行不同的处理,他们确实这样做了

【讨论】:

  • FWIW,clang 的行为正是我所期望的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
相关资源
最近更新 更多