Какой компилятор правильный?
Clang прав.
Определение функции constexpr
согласно dcl.constexpr / 3
Определение функции constexpr
должно удовлетворять следующему
Требования:
(3.1) его возвращаемый тип должен быть литеральным типом;
(3.2) каждый из его типов параметров должен быть литеральным типом;
(3.3) его тело функции должно быть = delete
, = default
или составной оператор
не содержит:
(3.3.1) определение asm,
(3.3.2) оператор goto,
(3.3.3) метка идентификатора,
(3.3.4) try-block или
(3.3.5) определение переменной не буквального типа или static или
продолжительность хранения потока или для которой не выполняется инициализация.
Также согласно dcl.constexpr / 5 :
Для constexpr
функции или конструктора constexpr, который не является ни
по умолчанию ни шаблон, если не существует значений аргумента , таких как
вызов функции или конструктора может быть оцененным
подвыражение основного константного выражения,
Foo(true)
может быть оценено как выражение константы ядра (т.е. 1
).
Кроме того, Foo(false)
может быть , но не обязательно для постоянной оценки.
ЗАКЛЮЧЕНИЕ
Таким образом, ошибка в GCC.
Большое спасибо @Barry, @aschepler и @BenVoigt за помощь в ответе.