Код ниже, это плохо сформированный отчет о недоставке или он правильно сформирован?
Clang принимает следующий код, но gcc отклоняет его.
void h() { }
constexpr int f() {
return 1;
h();
}
int main() {
constexpr int i = f();
}
Вот сообщение об ошибке:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'constexpr int f()':
main.cpp:5:6: error: call to non-'constexpr' function 'void h()'
h();
~^~
main.cpp: In function 'int main()':
main.cpp:9:24: error: 'constexpr int f()' called in a constant expression
constexpr int i = f();
~^~
main.cpp:9:19: warning: unused variable 'i' [-Wunused-variable]
constexpr int i = f();
Это вполне может иметь место, когда оба компилятора верны, если мы рассмотрим [dcl.constexpr]/5, учитывая, что f()
не является константным выражением, так как не удовлетворяет [expr.const]/(4.2), как он вызывает функцию non-constexpr h
. То есть код неверен, но никакой диагностики не требуется.
Еще одна возможность состоит в том, что код правильно сформирован, так как [expr.const]/(4.2) в этом случае не применяется, поскольку вызов h
в f
не оценивается. Если это так, то gcc
неверен, а clang
верен.
Ответы
Ответ 1
Clang это правильно. Вызов f()
является константным выражением, поскольку вызов функции h()
никогда не вычисляется, поэтому [dcl.constexpr]/5 не применяется. Вызов h()
в теле функции f()
не является constexpr
поскольку ограничения на функции constexpr
ничего не говорят о том, что нельзя constexpr
функции non- constexpr
. Действительно, функция, подобная следующей, правильно сформирована, потому что вызов ее может быть константным выражением, когда x
нечетно:
constexpr int g(int x) {
if (x%2 == 0) h();
return 0;
}