Правильно ли определены не завершающие функции constexpr?

Рассмотрим следующий код:

constexpr unsigned f(unsigned x)
{
    while (x & 1) x *= 3;
    return x;
}

int main()
{
    char a[f(2)];
    char b[f(1)];
}

Если это не очевидно: для нечетных целых чисел x функция f никогда не завершается.

Когда я компилирую приведенную выше программу с clang на coliru, b кажется VLA, но не a:

warning: variable length arrays are a C99 feature [-Wvla-extension]

char b[f(1)];

Существует ли четко определенный предел, при котором компилятор решает прекратить вычисление константного выражения? Или было бы совершенно нормально, если бы соответствующий компилятор вошел в бесконечный цикл? f(1) дает UB?


person fredoverflow    schedule 05.03.2014    source источник
comment
Альтернативное название: Решает ли constexpr проблему остановки? (шучу, конечно)   -  person stefan    schedule 06.03.2014


Ответы (1)


Есть ряд вещей, которые означают, что выражение не является основным константным выражением.

-- вызов функции constexpr или конструктора constexpr, который превысит ограничения рекурсии, определенные реализацией;

(пятый пункт в §5.19/2.). Таким образом, предел определяется реализацией.

person James Kanze    schedule 05.03.2014
comment
Оказывается, С++ 14 изменил это выражение на простое выражение, которое превышало бы ограничения, определенные реализацией, чтобы покрыть также нерекурсивные ограничения, в этом случае полные выражения оцениваются в основном постоянном выражении. - person Johannes Schaub - litb; 05.03.2014
comment
См. Приложение B: Полные выражения, оцениваемые в основном постоянном выражении [1 048 576]. - person Sebastian Redl; 05.03.2014
comment
@JohannesSchaub-litb Да. Я начал искать, а потом потерял исходное выражение. Хороший вопрос: должны быть какие-то ограничения, иначе компилятор никогда не остановится. - person James Kanze; 05.03.2014
comment
Прямо сейчас правильные цитаты находятся в комментариях, но они должны быть в ответе, чтобы мы могли удалить комментарии как устаревшие. - person Shafik Yaghmour; 06.03.2014