constexpr int func(int rf){
constexpr int v = rf; // #1
return 0;
}
int main(){
}
Рассмотрим приведенный выше код, компилятор жалуется, что такой код - ill-formed
. результат здесь:
error: 'rf' is not a constant expression
При этом выражение в месте, отмеченном # 1, оценивается компилятором. Я согласен с тем, что rf
не является постоянным выражением, потому что оно нарушает следующие правила:
Выражение e является основным постоянным выражением, если при вычислении e, следуя правилам абстрактной машины, не будет оцениваться одно из следующих выражений:
expr.const # 2преобразование lvalue-to-rvalue, если оно не применяется к
- энергонезависимое значение glvalue целочисленного или перечисляемого типа, которое относится к полному энергонезависимому константному объекту с предшествующей инициализацией, инициализированному константным выражением, или
- энергонезависимое значение glvalue, которое относится к подобъекту строкового литерала, или
- энергонезависимое значение glvalue, которое относится к энергонезависимому объекту, определенному с помощью constexpr, или которое относится к неизменяемому подобъекту такого объекта, или
- энергонезависимое значение glvalue литерального типа, которое относится к энергонезависимому объекту, время существования которого началось в пределах вычисления e;
Однако меня смущает то, что я нигде в своем примере не вызывал функцию func
, почему компилятор оценивает выражение rf
? Из-за этого я не понимаю, что такое evaluation
, а что execution
.
Согласно этому правилу:
intro.execution # 18 а>
При вызове функции (независимо от того, является ли функция встроенной) каждое вычисление значения и побочный эффект, связанный с любым выражением аргумента или с постфиксным выражением, обозначающим вызываемую функцию, упорядочиваются перед выполнением каждого выражения или оператора в теле вызываемая функция. Для каждого вызова функции F, для каждой оценки A, которая происходит в F, и каждой оценки B, которая не встречается в F, но оценивается в том же потоке и как часть одного и того же обработчика сигнала (если есть), либо A упорядочивается до B или B находится в последовательности перед A.
Это звучит так, только если вызывается соответствующая функция, тогда выполняется оценка для выражения, которое находится в теле функции.
Однако очевидно, что я не называл func
в моем примере. Итак, мои вопросы:
Вопрос 1:
в какой ситуации будет выполняться оценка выражений?
Для постоянных выражений существует только грубый подсказка в стандарте, то есть [Note: Constant expressions can be evaluated during translation. — end note]
, больше нет.
Вопрос 2:
В отличие от этого, если оператор в # 1 будет int v = rf;
, оценивает ли компилятор такое выражение rf
во время перевода, если я не вызываю функцию func
?
Вопрос 3:
в чем разница между evaluation
и execution
?
Вопрос 4:
где соответствующий пункт в стандарте определяет, в какой ситуации будет происходить оценка выражений?
At parsing time, it just consider the expression is ill-formed
, вот в чем вопрос. Еслиrf
не вычисляется так называемой абстрактной машиной, какmachine
может узнать, является лиrf
постоянным выражением или нет? Поскольку компилятор жалуется, чтоrf
не является константным выражением, то, как говорится,rf
оценивается, чтобы определить, является оно или нет. - person xmh0511   schedule 28.08.2020expressions
, которые должны быть константными выражениями во время компиляции, независимо от того, будет ли такая сущность выполняться во время выполнения. Однако в абстрактной машине нет соответствующего пункта. - person xmh0511   schedule 28.08.2020constexpr
внутриfunc
. Поскольку этоconstexpr
, он хочет его оценить (в отличие от регулярного выражения, в котором он оценивает его правильность). На этом этапе он не может оценить его какconstexpr
, потому чтоrf
не является константным выражением. - person nop666   schedule 28.08.2020#1
rf
должно иметь право быть постоянным выражением. - person xmh0511   schedule 28.08.2020