Partage
  • Partager sur Facebook
  • Partager sur Twitter

référence à une variable locale (cmpt indéfini)

C++11/14

Sujet résolu
    6 novembre 2018 à 19:09:13

    Salut OC,

    je termine le conseil 3, et j'arrive sur une situation de code à laquelle j'ai déjà probablement eu affaire plusieurs fois et qui a pu peut-être causer des bugs :

    Voici le code proposé par Scott Meyers page 29 :

    decltype(auto) f1()
    {
    int x=0;
    ...
    return x;
    }
    
    decltype(auto) f2()
    {
    int x=0;
    ...
    return (x);   ///decltype((x)) donne int&, donc f2 renvoie un int&
    }

     Il dit ensuite "Notez que non seulement f2 a un type de retour différent de f1, mais qu'elle renvoit également une référence à une variable locale! C'est le genre de code qui conduit à coup sûr vers un comportement indéfini"

    1) Veut-il dire que c'est une mauvaise pratique ?

    2) ou bien pire que renvoyer une référence vers une variable qui sera détruite à la sortie de fonction est dangereux ?

    3) Dans ce cas, j'imagine que la solution pour gérer cela, c'est de faire en sorte que x apparaisse dans les paramètres de la fonction ?

    Merci


    "Programmez efficacement en C++, de Scott Meyers (Dunod). Copyright 2016 Dunod pour la version française 978-2-10-074391-9, et 2015 Scott Meyers pour la versio d'origine 978-1-491-90399-5"

    -
    Edité par pseudo-simple 6 novembre 2018 à 19:19:21

    • Partager sur Facebook
    • Partager sur Twitter
      6 novembre 2018 à 19:12:56

      Lu'!

      Comportement indéfini, ça veut dire ce que ça veut dire : tu ne sais pas ce que va générer un compilateur, et rien dans la norme ne le dit. Communément, ça fait n'importe quoi.

      • Partager sur Facebook
      • Partager sur Twitter

      Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

        6 novembre 2018 à 19:16:05

        Merci Ksasspeuk :) c'est clair.

        Quelle solution pour remédier à la situation où tu crées une variable locale dans une fonction, et que tu souhaites impérativement l'envoyer en retour de fonction ?

        Merci à toi

        -
        Edité par pseudo-simple 6 novembre 2018 à 19:17:13

        • Partager sur Facebook
        • Partager sur Twitter
          6 novembre 2018 à 19:28:34

          YES, man a écrit:

          Merci Ksasspeuk :) c'est clair.

          Quelle solution pour remédier à la situation où tu crées une variable locale dans une fonction, et que tu souhaites impérativement l'envoyer en retour de fonction ?

          Merci à toi

          -
          Edité par YES, man il y a 9 minutes

          Tu retourne une copie parce que tu ne pourra jamais renvoyer une reference locale .. ( logique car detruite a la fin du scope .. )

          • Partager sur Facebook
          • Partager sur Twitter
            6 novembre 2018 à 19:30:29

            Ta question est étrange, puisque la réponse est dans ton premier message : retourner par valeur, pas par référence.

            Et ce problème n'est pas spécifique a decltype(auto), il ne fait qu'ajouter une couche de caca sur un problème que tu devrais connaitre.

            Zérotisme a écrit:

            Tu retourne une copie parce que tu ne pourra jamais renvoyer une reference locale .. ( logique car detruite a la fin du scope .. )

            Attention : "par valeur" ne veut pas dire "par copie". Cela peut faire un move de la variable locale, voire ne pas avoir de surcout si le (N)RVO s'applique.

            -
            Edité par gbdivers 6 novembre 2018 à 19:38:09

            • Partager sur Facebook
            • Partager sur Twitter
              6 novembre 2018 à 19:49:53

              @gbdivers : j'ai un doute sur un problème qui va peut-être te sembler un truc de base, mais j'ai besoin d'éclaircir ça :

              je suis d'accord pour retourner par valeur. mais est-ce que le problème ne reste pas le même puisque même si j'ai une variable locale x dans une fonction avec

              int x=0;


              à la sortie du scope, la variable locale est détruite, donc est-ce que ça ne pose pas un problème de retourner par valeur une variable détruite en sortie de scope ?

              tentative de réponse : Si j'ai raison, quand on dit par valeur (en entrée comme en sortie), c'est une copie en fait qui est créée et renvoyée. Donc dans ce cas, ça résout le problème, mais je voudrais juste m'en assurer.

              Merci pour tes éclaircissements

              -
              Edité par pseudo-simple 6 novembre 2018 à 19:52:40

              • Partager sur Facebook
              • Partager sur Twitter
                6 novembre 2018 à 20:11:48

                YES, man a écrit:

                tentative de réponse : Si j'ai raison, quand on dit par valeur (en entrée comme en sortie), c'est une copie en fait qui est créée et renvoyée. Donc dans ce cas, ça résout le problème, mais je voudrais juste m'en assurer.

                Non.

                Comme je l'ai dit dans mon précédent message, "par valeur" peut etre une copie ou un move ou un (N)RVO. Dans tous les cas, ca ne pose pas de problème.

                Le problème provient uniquement quand on retourne une indirection (reference, pointeur, iterateur, etc) d'une variable local en dehors de sa portée.

                • Partager sur Facebook
                • Partager sur Twitter
                  6 novembre 2018 à 21:48:05

                  Peux-tu préciser ce qu'est l'acronyme (N)RVO  ?

                  Merci à toi

                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 novembre 2018 à 21:58:58

                    Non, le forum n'est pas un cours. Fais des recherches, prends un cours. Et s'il y a des choses que tu ne comprends pas, on t'aidera.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      6 novembre 2018 à 22:23:42

                      https://en.wikipedia.org/wiki/Copy_elision
                      • Partager sur Facebook
                      • Partager sur Twitter
                        7 novembre 2018 à 9:32:27

                        Tu tombes à pic. J'en ai justement parlé ici : https://openclassrooms.com/forum/sujet/pas-de-compilation-avec-les-pointeurs-ds-poorpg#message-92740774

                         Contrairement à ce que dit Ksass'Peuk, c'est bien défini par la norme que les parenthèses changent le comportement lors de l'utilisation du decltype :

                        https://stackoverflow.com/questions/4762662/are-parentheses-around-the-result-significant-in-a-return-statement/25615981#25615981

                        En conclusion : ne jamais utiliser return (blabla).

                        -
                        Edité par markand 7 novembre 2018 à 9:35:38

                        • Partager sur Facebook
                        • Partager sur Twitter

                        git is great because Linus did it, mercurial is better because he didn't.

                          7 novembre 2018 à 10:05:34

                          markand a écrit:

                          Contrairement à ce que dit Ksass'Peuk, c'est bien défini par la norme que les parenthèses changent le comportement lors de l'utilisation du decltype


                          Ksass n'a pas dit le contraire, il donne juste la définition d'un UB

                          Mais l'UB ici ne provient pas de l'utilisation de decltype, c'est le retour de référence d'une variable locale le soucis, decltype(auto) ne fais que l'obfusquer

                          markand a écrit:

                          En conclusion : ne jamais utiliser return (blabla).


                          Quand on utilise la déduction de type, mais perso la grande majorité de mes fonctions sont déclarées de manière explicite

                          Après c'est vrai que je ne vois pas trop l'intérêt des parenthèses, surtout autour d'une id-expr

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Dream on, Dream on, Dream until your dream comes true
                            7 novembre 2018 à 14:13:07

                            Merci les gars, vous êtes forts
                            • Partager sur Facebook
                            • Partager sur Twitter
                              8 novembre 2018 à 9:58:24

                              romantik a écrit:

                              markand a écrit:

                              Contrairement à ce que dit Ksass'Peuk, c'est bien défini par la norme que les parenthèses changent le comportement lors de l'utilisation du decltype


                              Ksass n'a pas dit le contraire, il donne juste la définition d'un UB

                              Au temps pour moi, j'avais mal interprété la phrase.

                              -
                              Edité par markand 8 novembre 2018 à 9:58:38

                              • Partager sur Facebook
                              • Partager sur Twitter

                              git is great because Linus did it, mercurial is better because he didn't.

                              référence à une variable locale (cmpt indéfini)

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown