Похоже, вы предполагаете, что если один компилятор прав, то другой должен ошибаться.Программа либо содержит ошибку (а затем компилятор, который принимает ее неправильно), либо ее нет (а затем компилятор, который отклоняет ее, неверен).Это, в свою очередь, основывается на неявном допущении, что рассматриваемая ошибка, а именно отсутствие определения объекта, используемого ODR, является диагностируемой ошибкой.К сожалению это не так.Стандарт прямо заявляет, что:
[ basic.def.odr / 10 ] Каждая программа должна содержать ровно одно определение каждой не встроенной функции или переменной, используемой odrв этой программе за пределами отклоненного утверждения; Диагностика не требуется .
Поскольку данное положение стандарта проблематично и нежелательно, оно есть.Ваша программа имеет неопределенное поведение из-за отсутствия определения, и для ее диагностики не требуется реализация.Таким образом, оба компилятора технически корректны на любом уровне оптимизации.
В C ++ 17 с обязательным удалением копии программа больше не содержит ODR-использования рассматриваемой переменной. Статические члены-члены constexpr неявно встроены, не являются отдельныминужно определение (спасибо Олив).