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()
は定数式ではないため、これは両方のコンパイラーが正しい場合である可能性があります。 constexpr以外の関数h
を呼び出すため、 [expr.const] /(4.2) を満たします。つまり、コードの形式は正しくありませんが、診断は必要ありません。
もう1つの可能性は、[expr.const] /(4.2)がこの場合適用されないため、コードの形式が正しいことです。これは、h
のf
への呼び出しが評価されないためです。この場合、gcc
は間違っており、clang
は正しいです。
Clangは正しいです。 f()
の呼び出しは評価されないため、h()
の呼び出しは定数式であり、[dcl.constexpr]/5は適用されません。 h()
の本体にあるf()
の呼び出しは、constexpr
関数の constraints が何も言っていないため、形式が正しくありません非constexpr
関数の呼び出しは許可されていません。実際、x
が奇数の場合、その呼び出しは定数式になる可能性があるため、次のような関数は整形式です。
constexpr int g(int x) {
if (x%2 == 0) h();
return 0;
}