Это должно быть правильно, так что это ошибка gcc.
В конечном итоге мы получим инициализацию агрегата через [stmt.return] p2 , что говорит:
… Оператор return с фигурным списком инициализации инициализирует объект или ссылку, которые будут возвращены из функции путем копирования-инициализации списка ([dcl.init.list]) из указанного списка инициализатора. ...
затем [dcl.init.list] p3.2 говорит:
В противном случае, если T является агрегатом, выполняется инициализация агрегата ([dcl.init.aggr]). ...
В этот момент мы можем задаться вопросом, является ли это сужающим преобразованием и, следовательно, плохо сформированным, но [dcl.init.list] p7 не имеет каких-либо положений, охватывающих этот случай, и никаких других случаев в [ dcl.init.list] применить, чтобы сделать это плохо сформированным.
Мы можем видеть на аналогичном примере, который удаляет enum из уравнения, но сохраняет битовое поле, показывает, что ни gcc, ни clang не дают нам диагностику сужающего преобразования, что, как мы ожидаем, имеет место, хотя эта похожая проблема покрыта [dcl.init.list] p7.4 хотя и не плохо сформирован:
struct S2 {
int e : 2 ;
int dummy ;
} ;
S2 foo( int x ) {
return {x, 100} ;
}
увидеть его в прямом эфире
Как видно, у gcc, похоже, нет проблем в других контекстах, т.е.
S f(E e1, int x) {
S s {e1,100} ;
return s;
}
Итак, у вас есть обходные пути.