Правила для constexpr
функций разработаны таким образом, что невозможно написать функцию constexpr
, которая имеет какие-либо побочные эффекты.
Требуя, чтобы constexpr
не имел побочных эффектов, для пользователя становится невозможным определить, где / когда он был фактически оценен.Это важно, поскольку функции constexpr
могут выполняться как во время компиляции, так и во время выполнения по усмотрению компилятора.
Если бы побочные эффекты были разрешены, тогда должны были бы быть некоторые правила относительно порядка вкоторый они будут наблюдать.Это было бы невероятно трудно определить - даже сложнее, чем проблема порядка инициализации static
.
Относительно простой набор правил, гарантирующих, что эти функции не будут иметь побочных эффектов, должен требовать, чтобы они были единичными.выражение (с некоторыми дополнительными ограничениями).Изначально это звучит ограниченно и исключает утверждение if, как вы заметили.Хотя этот конкретный случай не будет иметь побочных эффектов, он привнесет дополнительную сложность в правила и, учитывая, что вы можете писать одни и те же вещи, используя троичный оператор или рекурсивно, это не так уж и сложно.
n2235 - это статья, в которой предлагается добавление constexpr
в C ++.В нем обсуждается рациональное для дизайна - соответствующая цитата, похоже, из цитаты из деструкторов, но в целом имеет отношение:
Причина в том, что выражение-константа предназначено для оценкикомпилятор во время перевода, как и любой другой литерал встроенного типа;в частности, не допускается никаких видимых побочных эффектов.
Интересно, что в статье также упоминается, что в предыдущем предложении компилятор автоматически выяснил, какие функции были constexpr
без нового ключевого слова, но это было найденобыть неосуществимо сложным, что, кажется, подтверждает мое предположение, что правила были разработаны как простые.
(Я подозреваю, что в ссылках, цитируемых в статье, будут другие цитаты, но это охватывает ключевой момент моегоаргумент про отсутствие побочных эффектов)