下面的代码是格式错误的NDR还是格式正确的?

时间:2019-04-18 18:59:28

标签: c++ language-lawyer c++17 constexpr

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();

考虑到f()不是一个常量表达式,因为它不满足[dcl.constexpr]/5,这两个编译器都是正确的,一旦我们考虑了[expr.const]/(4.2),它调用一个非constexpr函数h。也就是说,代码格式错误,但是不需要诊断。

另一种可能性是代码格式正确,因为[expr.const] /(4.2)在这种情况下不适用,因为未评估对h中的f的调用。在这种情况下,gcc是错误的,clang是正确的。

1 个答案:

答案 0 :(得分:24)

C语是正确的。对f()的调用是一个常量表达式,因为从未评估对h()的调用,因此[dcl.constexpr] / 5不适用。 h()主体中对f()的调用没有格式错误,因为constexpr函数上的constraints并没有说明不允许调用非{ {1}}功能。确实,如下所示的函数格式正确,因为当constexpr为奇数时,对其的调用可以是一个常量表达式:

x