Partage
  • Partager sur Facebook
  • Partager sur Twitter

Référence sur objet local, chemins de contrôle

C++

    21 mars 2019 à 17:24:30

    Bonjour,

    J'ai 2 questions :

    1) Je suppose que j'ai :

    Widget f(){
    Widget w;
    return std::move(w);
    }



    Pourquoi peut-on dire que l'élément retourné n'est pas l'objet local w, mais  une référence sur w ? En quoi std::move(w) produirait-il une référence sur w ?

    Je ne saisis pas.

    2) "lorsque différents chemins de contrôle dans une fonction renvoient des variables locales différentes" :

    Pouvez-vous me donner un exemple de cette situation car je n'ai pas saisi ce que ça veut dire.

    Par avance Merci pour votre aide

    -
    Edité par pseudo-simple 21 mars 2019 à 20:00:47

    • Partager sur Facebook
    • Partager sur Twitter
      21 mars 2019 à 18:18:39

      Pour la deuxième question (sans contexte), sa semble simplement être cela :

      int foo(bool condition) {
      
      	int answer{ 42 };
      
      	//some work
      
      	if (condition) {
      		return answer;
      	}
      
      	int other_answer{answer + 2 };
      
      	//some work...
      
      	return other_answer;
      }

      Les variables answer et other_answer sont deux variables locales, chacune renvoyer selon 2 chemins de contrôles différents

      • Partager sur Facebook
      • Partager sur Twitter
        21 mars 2019 à 18:56:42

        YES, man a écrit:

        Pourquoi peut-on dire que l'élément retourné n'est pas l'objet local w, mais  une référence sur w ? En quoi std::move(w) produirait-il une référence sur w ?

        C'est quoi la signature de std::move ? Quel type cette fonction retourne-t-elle ?
        • Partager sur Facebook
        • Partager sur Twitter
          21 mars 2019 à 19:21:24

          Je viens de compléter le code

          • Partager sur Facebook
          • Partager sur Twitter
            21 mars 2019 à 19:37:47

            Tu n'as pas lu correctement mes questions.
            • Partager sur Facebook
            • Partager sur Twitter
              22 mars 2019 à 17:46:12

              Si tu regarde l'implémentation de std::move, elle est équivalente à :
              Widget f(){
              Widget w;
              return static_cast<Widget&&>(w);
              }
              Donc elle change la Lvalue "w" en Rvalue, ce qui a pour effet d'appeler le constructeur par déplacement, au lieu de celui par copy

              Sauf qu'ici, en obligeant l'appel de move, tu empêche l'optimisation NRVO qui permet d'éliminer tout objets temporaires.

              Si tu ajoute des conditions, le compilateur pourrait ne pas optimiser par élision et il utiliser implicitement "std::move" à la place

              T Bob(bool k)
              {
                  T a, b;
                  return k ? a : b;            // lvalue expression, copied
                  return std::move(k ? a : b); // moved
                  if (k)
                      return a;                // moved, and possibly elided
                  else
                      return b;                // moved, and possibly elided
              }
              • Partager sur Facebook
              • Partager sur Twitter

              GZE, un moteur multiplateforme, adapté pour de la 2D, 3D et création de logiciels.

                22 mars 2019 à 17:50:10

                C'est cool de donner les réponses. Mais ca permet juste de donner les réponses, pas de savoir si les gens ont compris les réponses. C'est quand meme mieux de les amener a trouver la reponse par eux meme.

                -
                Edité par gbdivers 22 mars 2019 à 17:50:43

                • Partager sur Facebook
                • Partager sur Twitter
                  22 mars 2019 à 18:21:46

                  Oui je comprend ton point de vue, mais j'ai l'impression que la question serait rester en suspend indéfiniment, ce qui n'est guère mieux. Aussi pour tout les autres qui sont intéresser à la question, je préfère donner un réponse complète.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  GZE, un moteur multiplateforme, adapté pour de la 2D, 3D et création de logiciels.

                    22 mars 2019 à 18:28:51

                    La derniere reponse de yesman date de 24h, c'est pas "indefiniement". 

                    Et a mon avis, ta réponse n'est pas complète, il y a une chose (probablement) que yesman n'a pas compris, d'où son error initiale.

                    -
                    Edité par gbdivers 22 mars 2019 à 18:30:10

                    • Partager sur Facebook
                    • Partager sur Twitter
                      22 mars 2019 à 18:41:32

                      Sans critiquer ton approche, pour ma part je considère que ce n'est pas un chat non plus, je ne vais pas stackoverflow pour avoir des réponses indirectes.
                      • Partager sur Facebook
                      • Partager sur Twitter

                      GZE, un moteur multiplateforme, adapté pour de la 2D, 3D et création de logiciels.

                        22 mars 2019 à 18:48:20

                        Merci beaucoup Maeiky. Je te remercie BEAUCOUP BEAUCOUP pour ces explications brillantes.

                        Il me semble que dans ton exemple :

                        return k ? a : b;            // lvalue expression, copied



                        il y un déplacement (pas une copie) car k est en paramètre de ta fonction. C'est un cas particulier dans le traitement de la NRVO

                        PS : le deuxième +1 sur ton message, c'est moi.

                        -
                        Edité par pseudo-simple 22 mars 2019 à 19:01:46

                        • Partager sur Facebook
                        • Partager sur Twitter
                          22 mars 2019 à 19:04:44

                          En effet quel homme brillant ce Maeiky ! :)

                          Mama ça fait teeeellement de zèle. La peur de l'ignorance me pique le nez tellement ça sent fort !

                          PS : faux le deuxième +1 c'était moi :)

                          -
                          Edité par Maluna34 22 mars 2019 à 19:06:13

                          • Partager sur Facebook
                          • Partager sur Twitter
                            22 mars 2019 à 19:44:51

                            YES, man a écrit:

                            Il me semble que dans ton exemple :

                            return k ? a : b;            // lvalue expression, copied



                            il y un déplacement (pas une copie) car k est en paramètre de ta fonction. C'est un cas particulier dans le traitement de la NRVO

                            Bon point! L'optimisation "RVO", ne peut avoir lieu si le compilateur ne peut connaître l'instance retourné (qui est connue seulement au runtime à cause de k)

                            Plus d'info ici

                            Edit:
                            Pour ce qui est de la copy au lieu du move, c'est un cas particulier:
                            "A conditional expression doesn't qualify as naming an object, so it must preform a copy."

                            -
                            Edité par Maeiky 22 mars 2019 à 21:02:40

                            • Partager sur Facebook
                            • Partager sur Twitter

                            GZE, un moteur multiplateforme, adapté pour de la 2D, 3D et création de logiciels.

                              22 mars 2019 à 21:07:22

                              Ce n'est pas une exception, c'est le type de retour de la ternaire qui détermine s'il y a RVO ou non. Une ternaire qui prend 2 lvalues retourne une lvalue: pas de RVO sur les lvalues. Que k soit une constante de compilation ou non ne change pas le résultat.

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Référence sur objet local, chemins de contrôle

                              × 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