Ответ 1
Ответ
Оба компилятора верны!
Объяснение
В стандарте не проводится различие между ошибкой и предупреждением, оба входят в категорию диагностики.
1.3.6
диагностическое сообщение[defns.diagnostic]
относящееся к определенному реализацией подмножеству выходных сообщений реализации
Поскольку стандарт говорит, что диагностика требуется в случае плохого формирования программы, например, когда сужение-преобразование происходит внутри инициализатора с фиксацией, оба компилятора подтверждают.
Даже если программа плохо сформирована с точки зрения стандартов, она не гарантирует, что компилятор прекратит компиляцию из-за этого; реализация может свободно делать все, что захочет, до тех пор, пока она выдает диагностику.
Причина поведения gcc?
Полезная информация была предоставлена @Jonathan Wakely через комментарии к этому сообщению, ниже - слияние двух комментариев;
он точная причина в том, что GCC сделал ошибку в какой-то момент, и он сломал ВСЕ ПРОГРАММЫ, поэтому вместо этого он превратился в предупреждение. Несколько человек, которые включили опцию
-std=c++0x
для больших кодовых баз С++ 03, обнаружили безвредные суживающие преобразования, чтобы заставить большую часть работы портирования перейти на С++ 11.
См., Например, PR 50810, где Alisdair сообщает о сужении ошибок, было 95% проблем в базе кода Bloomberg.
В этом тот же PR вы можете видеть, что, к сожалению, это был не случай "давайте просто выпустить предупреждение и сделать с ним", потому что для правильного поведения потребовалось много усилий.