Clang accepte le code suivant, mais gcc le rejette .
void h() { }
constexpr int f() {
return 1;
h();
}
int main() {
constexpr int i = f();
}
Voici le message d'erreur:
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();
Cela pourrait bien être le cas lorsque les deux compilateurs sont corrects, une fois que nous considérons [dcl.constexpr]/5 , étant donné que f()
n'est pas une expression constante, car elle ne le fait pas satisfaire [expr.const]/(4.2) , car il appelle une fonction non constexpr h
. Autrement dit, le code est mal formé, mais aucun diagnostic n'est requis.
Une autre possibilité est que le code soit bien formé, car [expr.const]/(4.2) ne s'applique pas dans ce cas car l'appel à h
dans f
n'est pas évalué. Si tel est le cas, gcc
est incorrect et clang
est correct.
Clang a raison. Un appel à f()
est une expression constante car l'appel à h()
n'est jamais évalué, donc [dcl.constexpr]/5 ne s'applique pas. L'appel à h()
dans le corps de f()
n'est pas mal formé car les fonctions contraintes sur constexpr
ne disent rien à propos de ne pas être autorisé à appeler des fonctions nonconstexpr
. En effet, une fonction comme la suivante est bien formée car un appel à celle-ci peut être une expression constante lorsque x
est impair:
constexpr int g(int x) {
if (x%2 == 0) h();
return 0;
}