Почему функция 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

(возможно, было добавлено ключевое слово, но не фактическая поддержка реализации)

Другие вопросы по тегам