Почему функция consteval допускает неопределенное поведение?
В C++ есть очень интересное свойство константных выражений: их оценка не может иметь неопределенного поведения (7.7.4.7):
Выражение e является основным постоянным выражением, если только оценка e, следуя правилам абстрактной машины ([intro.execution]), не оценила бы одно из следующего:
...
операция, которая будет иметь неопределенное поведение, как указано в [intro] - [cpp] этого документа [Примечание: включая, например, целочисленное переполнение со знаком ([expr.prop]), определенную арифметику указателя ([expr.add]), деление на ноль или определенные операции сдвига - конечная нота];
Пытаясь сохранить ценность 13!
в constexpr int
действительно дает хорошую ошибку компиляции:
constexpr int f(int n)
{
int r = n--;
for (; n > 1; --n) r *= n;
return r;
}
int main()
{
constexpr int x = f(13);
return x;
}
Выход:
9:19: error: constexpr variable 'x' must be initialized by a constant expression
constexpr int x = f(13);
^ ~~~~~
4:26: note: value 3113510400 is outside the range of representable values of type 'int'
for (; n > 1; --n) r *= n;
^
9:23: note: in call to 'f(3)'
constexpr int x = f(13);
^
1 error generated.
(Кстати, почему в ошибке написано "вызов" f(3) ", а это вызов f(13)?..)
Затем я удаляю constexpr
от x
, но сделать f
а consteval
. Согласно документам:
consteval - указывает, что функция является немедленной функцией, то есть каждый вызов функции должен производить константу времени компиляции
Я действительно ожидаю, что такая программа снова вызовет ошибку компиляции. Но вместо этого программа компилируется и запускается с UB.
Это почему?
UPD: Комментаторы предположили, что это ошибка компилятора. Я сообщил об этом: https://bugs.llvm.org/show_bug.cgi?id=43714
1 ответ
Это ошибка компилятора. Или, если быть более точным, это "недоработанная" функция (см. Комментарий в bugzilla):
Ага - похоже, consteval еще не реализован, согласно: https://clang.llvm.org/cxx_status.html
(возможно, было добавлено ключевое слово, но не фактическая поддержка реализации)