Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre habitué
    traitement des fonctions constexpr au runtime
    Bonjour,

    J'ai vu ça et là sur le net que les fonctions static constexpr étaient traitées au moment de la compilation. Ok, mais possèdent-elles aussi le comportement de fonctions standard lors du runtime ?

    Est-ce une fausse bonne idée que de définir tous ses opérateurs en constexpr, lorsque ces dernier sont très simples mais aussi destinés à une utilisation dynamique ?


    Merci d'avance.

  2. #2
    Responsable 2D/3D/Jeux

    Bonjour,

    Les fonctions constexpr, sont évaluée à la compilation. Cela veut dire que :
    • le compilateur va les interpréter au moment de la compilation ;
    • lors d'un appel à la fonction constexpr, le compilateur va utiliser l'interprétation de la fonction pour donner le résultat. Imaginons :
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      constexpr int add(int a, int b) {
          return a + b;
      }

      Un exemple simple, certes. Il faut savoir que lors de la compilation, l'appel à res = add(5,10) fera que le compilateur va remplacer la ligne, par son résultat. En bref, dans l'exécutable, la ligne sera devenue : res = 15;. Le reste (l'opération) a été résolu au moment de la compilation. Toutefois, cela impose une autre contrainte : les arguments de cette fonction add() doivent être connus au moment de la compilation.


    Ok, mais possèdent-elles aussi le comportement de fonctions standard lors du runtime ?
    Je dois dire que je ne comprends pas très bien la question.

    lorsque ces dernier sont très simples mais aussi destinés à une utilisation dynamique ?
    Du coup, non.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre expert
    Citation Envoyé par LittleWhite Voir le message
    Les fonctions constexpr, sont évaluées à la compilation.
    Peut être évaluée à la compilation. Cela fait toute la différence, une fonction constexpr fonctionne aussi au runtime, elle ne diffère pas des autres fonctions. La seule différente va se situer sur les contraintes d'implémentation: elle ne peut utiliser que des expressions/fonctions marquées constexpr auquel cas elle ne sera jamais constexpr. Et encore, cela se limite à la branche de code utilisée pendant une résolution compile-time.

    Au niveau des fonctions constexpr, la différence et encore plus subtile: ce n'est pas la fonction qui décide si le résultat sera évalué à la compilation, mais le contexte d'appel (contrairement à consteval c++20)).

  4. #4
    Membre habitué
    Super, c'est ce que je voulais savoir ! Donc si c'est le contexte qui joue, cela veut dire, si j'ai bien compris, que la fonction est évaluée au compile-time si la situation s'y prête, et au run-time pour les autres cas.
    Si c'est ça, c'est parfait à mon goût !

    D'ailleurs, ce système existe-t-il aussi en C (quand même plus pratique que les macros :/) ?


    Merci.

  5. #5
    Membre expert
    Citation Envoyé par BioKore Voir le message
    D'ailleurs, ce système existe-t-il aussi en C (quand même plus pratique que les macros :/) ?
    Non, c'est une fonctionnalité assez complexe aussi niveau des compilateurs, c'est un peu comme avoir un interpréteur/vm de code dans le compilateur, ça ne me semble pas dans la philosophie de C d'ajouter une telle complexité au niveau des compilateurs.

  6. #6
    Membre habitué
    Effectivement, vu comme ça, on peut comprendre que les compilateurs C n'intègrent pas de tel systèmes.

    Mais d'ailleurs, pour en revenir au C++, cela ne veut-il pas dire qu'il est intéressant de déclarer l'ensemble des fonctions de son programme (lorsque celles-ci s'y prêtent) en constexpr ?
    C'est ce que j'ai fait dans un petit bout de code fait il y a quelques temps ; j'ai tout passé (ou presque) en constexpr ; je n'ai pas fait de tests de performances mais les tests semblent indiquer que tout fonctionne correctement. Fausse bonne idée ?

    Merci.

  7. #7
    Membre expert
    En mettant tout en constexpr, l'effet principalement visible va être: ça ne compile plus. Ce qui est de moins en moins vrai puisque de plus en plus de chose sont constexpr (allocation dynamique, algorithmes de la stl, etc). Pour un code qui existe déjà, passé cela, rien ne change niveau fonctionnalité. Sur les performances, le compilateur aura tendance à faire un plus souvent les calculs à la compilation, mais c'est très dépendant, il ne faut pas s’attendre à des miracles.

    La question à se poser est « Cette fonction est-elle utile dans un contexte compile-time ? », ce qui dépend beaucoup de son rôle.

    - Une fonction lit un fichier ; même pas envisageable.
    - Une fonction qui parse des lignes ; pour quoi faire ?
    - Une fonction min ; oui, c'est utile.

    Je ne pense pas qu'il y a de réponse universelle, c'est du cas par cas.

  8. #8
    Membre habitué
    Bien entendu, dans mon cas, les fonctions restent simples et, je pense, s'inscrivent plutôt bien dans le contexte de constexpr.
    Par exemple, dans le cas présent, il s'agit principalement d'opérateurs simples (ex: return ax +b) voire de fonctions simples de la stl comme std::transform.
    Dans mon cas, pas d'erreurs ni de warnings de la part de gcc -Wextra et les tests semblent fonctionner correctement.

    Pour les perfs, effectivement, ça ne sera probablement pas transcendent mais qui peut le plus peut le moins donc si cela ne présente pas d'incompatibilité, ça me semble être une 'bonne' pratique.

    Après, comme tu dis, c'est au cas par cas et l'objet n'est pas non plus de tout passer en constexpr sans réfléchir.

    Une corde de plus à mon arc ! Merci pour les détails.