IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

C++ Discussion :

Reference et retour de fonction par valeur


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Par défaut Reference et retour de fonction par valeur
    Bonjour,

    Je suis tombé il y a quelques jours sur un blog qui montrait, dans son exemple sur les références le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Retour
    {
    public:
       void g() const {}
    };
     
    Retour f() { return Retour(); }
     
    int main(int argc, char *argv[])
    {
        const Retour &retour = f();
        retour.g();
        return 0;
    }
    Le blog expliquait que l'assignation de la variable de retour de la fonction a une référence permettait de s'alléger d'une copie.

    Je ne trouve aucune autre références à cette pratique sur le net et n'ai rien lu non plus qui parle de cela dans les bouquins de Sutter/Meyers qui parlent des bonnes pratiques.

    Je me demande donc si cette optimisation est vraiment une bonne pratique, selon vous ?

  2. #2
    Membre chevronné Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Par défaut
    Alors si j'ai tout bien compris du c/c++ ... (ce qu'est pas dit)

    Il y a un premier objet de type Retour créé ici

    Comme la fonction retourne l'objet par valeur, un deuxième objet est créé et copié à partir du premier.

    Ensuite si tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const Retour retour = f();
    alors un troisième objet de type Retour est créé puis copié à partir du deuxième. Alors que si tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const Retour & retour = f();
    Il n'y a pas de troisième objet créé ni même copié mais la référence de l'objet retourné par la fonction est stocké dans la référence retour.

    Les constructeurs par déplacement à venir (si j'ai tout bien compris encore) pourront réduire le nombre de créations/copies dans les 2 cas de 1.

    Flo.

    Voilà

  3. #3
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    616
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 616
    Par défaut
    Cela évite bien une recopie mais ne risque-t-on pas de faire une référence vers un objet qui vas être dépiler ? En cascadant les fonction du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Retour f(){ return Retour(); }
     
    void h(Retour& r){ r = f(); }
     
    int main(){
      Retour r;
      h(r);
      // Ici, r serait une référence vers une variable local de f, donc qui n'existe plus...
    }
    Ce code ne compile pas mais c'est pour montrer l'idée. (En remplaçant les ref par des pointeurs, ça compile et ça montre parfaitement pourquoi les pointeurs sont dangereux ).

  4. #4
    screetch
    Invité(e)
    Par défaut
    j'ai beau tester avec différents compilateurs et avec du code a effet de bord, le code que tu montres n'effectue pas de copie sur sunCC, gcc et msvc.

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Oui c'est tout à fait normal.

    Dans le cas normal il devrait y avoir :
    - Construction dans le scope de la fonction
    - Copie dans un objet temporaire hors du scope de la fonction
    - Affectation à une référence constante (le consante est important car c'est un objet temporaire).

    Or il y a des règles (nommées copy-elision dans la norme, et souvent distingués en 3 catégorie)

    - (N)RVO : (Le N c'est pour Named) Permet au compilateur de construire directement l'objet dans l'objet temporaire hors du scope de la function si celui ci a le même type de base que le type de retour

    - Copy-Elision : Permet au compilateur de construire directement dans un objet qui devrait être copié depuis un temporaire quand ceux-ci ont le même type de base.

    Marche aussi pour la move-semantic (et cf norme pour les détails, il y a d'autre cas de cette règle plus spécifique).

    Dans ton cas c'est la première règle qui s'applique, si tu enlèves la référence constante et tu verras qu'il n'y a aussi qu'une construction, la seconde règle se combine ainsi à la première.

    A noter que le compilateur PEUT faire ces optimisation mais qu'il n'est pas obligé de les faire. Cependant ca a une incidence sur notre facon de coder : il ne faut pas que nos constructeur de copie / destructeur (/move-ctor) aient des effets de bord, ie qu'il ne fasse pas autre chose que copier/détruire, sinon l'optimisation du compilateur risque d'avoir des effets inatendues sur notre code.

Discussions similaires

  1. Retour de fonction par référence?
    Par ternel dans le forum Langage
    Réponses: 27
    Dernier message: 10/05/2014, 18h17
  2. Réponses: 2
    Dernier message: 09/12/2010, 20h52
  3. [POO] Retour de données par une fonction (return)
    Par webrider dans le forum Langage
    Réponses: 6
    Dernier message: 26/08/2006, 21h49
  4. Fonctions et valeur par default
    Par Goundy dans le forum C
    Réponses: 5
    Dernier message: 27/02/2006, 22h16
  5. fonction operator, valeur de retour
    Par butch dans le forum C++
    Réponses: 21
    Dernier message: 20/09/2004, 10h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo