2014-02-05 4 views
10

Возможно, я обнаружил ошибку с GCC v4.8.2, но сначала хочу проверить, прежде чем я отправлю ее, поскольку это может быть мне что-то не так!Это ошибка GCC? Инициализация структур с помощью объединений

Следующий код:

#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. 

я представить это как ошибку, если никто не имеет каких-либо идей, хотя в моем опыте проблема программисты почти никогда не ошибка компилятора и почти всегда по своей вине!

+8

'Пожалуйста, отправьте полный отчет об ошибке 'уже ответ –

+23

Внутренняя ошибка компилятора всегда является ошибкой компилятора. – soon

+0

Технически я бы сказал, что для компиляции это должно требовать '-std = g ++ 11', поскольку назначенные инициализаторы (или то, что они называются) являются C, а не C++. – Angew

ответ

3

Как указано в комментариях выше: Любое сообщение об ошибке, которое вы получаете от GCC, которое включает в себя фразы internal compiler error и Please 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, где Дуги Грегор спрашивает, как компилятор должен интерпретировать такие вещи, как

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), а последний - на плохо сформированный. В принципе, это нестандартная конструкция: разные компиляторы находятся в пределах своих прав, чтобы относиться к ней по-другому, , и они делают.

+0

FWIW, поведение клана - именно то, чего я ожидал. – hvd