web-dev-qa-db-fra.com

Qu'est-ce qui détermine si une fonction de consexpr est une expression constante?

(Compilateur utilisé est GCC avec C++ 17 autant que je sache (difficile à trouver cela dans Visual Studio))

#include <iostream>

using namespace std;

void increment( int& v )
{
    ++v;
}

int constexpr f()
{
    int v = 0;
    increment( v );
    return v;
}

int main( )
{
    cout << f( ) << '\n';
}

Le code ci-dessus donne l'erreur de compiler:

la fonction Constexport 'F' ne peut pas entraîner une expression constante.

Si je comprends bien, c'est parce que la fonction increment n'est pas un consexport. Ce qui me confond est que le code suivant compile bien:

#include <iostream>

using namespace std;

void increment( int& v )
{
    ++v;
}

int constexpr f()
{
    int v = 0;
    for( int i = 0; i < 1; ++i )
    {
        increment( v );
    }   
    return v;
}

int main( )
{
    cout << f( ) << '\n';
}

Ce code est fonctionnel de la même manière et compile, même si l'incrément n'est toujours pas un consexport. Je ne comprends pas comment il est possible qu'une boucle à boucle à travers la plage [0, 1) provoque la réalisation du compilateur que la fonction f est en fait une consexpr.

Si quelqu'un peut donner des idées sur Constexpr en C++ et cette incohérence apparente, je l'apprécierais grandement.

29
mchl12

La norme nécessite qu'une fonction constexpr soit effectivement évaluable au moment de la compilation pour certains jeu de paramètres mais pas tous. Il ne nécessite pas que les compilateurs diagnostiquent une fonction constexpr faisant certaines choses qui pourraient être non compilées dans certaines circonstances, ou même si une telle fonction a un tel ensemble de paramètres. Cela les évite d'avoir à résoudre le problème d'arrêt.

0
Sneftel