web-dev-qa-db-fra.com

Le code ci-dessous est-il un NDR mal formé ou bien formé?

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.

24
Alexander

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;
}
24
Brian