Возможно, я обнаружил ошибку в 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.
Я отправлю это как ошибку, если у кого-то нет идей, хотя по моему опыту проблема программистов почти никогда не является ошибкой компилятора и почти всегда его собственной ошибкой!
Как ответили в комментариях выше: Любое сообщение об ошибке, которое вы получаете от GCC, которое включает фразы internal compiler error
а также Please submit a full bug report
это определенно ошибка компилятора, а не ваша вина! В этом случае ошибка, по-видимому, связана с анализом GCC {{ ... }}
в режиме C ++, где «...
«включает в себя назначенный инициализатор. @Sam сообщил об этом как GCC ошибка 59832.
Однако, как указал @Angew, эта строка —
messages_.push_back({{ .byte = 'a' }});
— является не действителен C ++. Стандарт C ++ не позволяет назначенные инициализаторы; это особенность C99, которая не была принята в C ++ (ни C ++ 11, ни C ++ 14).
Что касается Зачем обозначенные инициализаторы было проблематично добавить в C ++, см. Вот, где Даг Грегор спрашивает, как компилятор должен интерпретировать такие вещи, как
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)
и последний как плохо сформированный. По сути, это нестандартная конструкция: разные компиляторы имеют право обращаться с ней по-разному, и они делают.
Других решений пока нет …