Clang接受以下代码,但是gcc rejects it。
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),因为它称为非constexpr函数h
。也就是说,代码格式错误,但不需要诊断。
另一种可能性是代码格式正确,因为[expr.const] /(4.2)在这种情况下不适用,因为不评估h
中对f
的调用。如果是这种情况,gcc
是错误的,clang
是正确的。
铿锵是对的。对f()
的调用是一个常量表达式,因为从不评估对h()
的调用,因此[dcl.constexpr] / 5不适用。在h()
体内对f()
的呼吁并不是形成的,因为constraints函数上的constexpr
没有说任何关于不被允许称为非constexpr
函数的事情。实际上,像下面这样的函数是格式良好的,因为当x
为奇数时,对它的调用可以是常量表达式:
constexpr int g(int x) {
if (x%2 == 0) h();
return 0;
}