Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4630 connectés 

 


Dernière réponse
Sujet : [C++]Pourquoi copier le retour d'une fonction ?
Musaran Si je mets un espion dans le constructeur de copie qui me produit un signal explicite, alors cela empêche une quelconque optimisation...
 
Comment mesurer sans modifier ? (problème connu)

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
Musaran Si je mets un espion dans le constructeur de copie qui me produit un signal explicite, alors cela empêche une quelconque optimisation...
 
Comment mesurer sans modifier ? (problème connu)
chrisbk

musaran a écrit a écrit :

J'ai compris mon erreur.

Code :
  1. //ceci ne génère pas de copie...
  2. C f(){
  3. return C() ;
  4. }
  5. //...mais ceci si.
  6. C f(){
  7. C o ;
  8. return o ;
  9. }

On peut donc faire un peu d'optimisation en construisant la valeur de retour dans l'expression du "return".




 
en release aussi ca genere qqchose ?

Musaran J'ai compris mon erreur.

Code :
  1. //ceci ne génère pas de copie...
  2. C f(){
  3. return C() ;
  4. }
  5. //...mais ceci si.
  6. C f(){
  7. C o ;
  8. return o ;
  9. }

On peut donc faire un peu d'optimisation en construisant la valeur de retour dans l'expression du "return".

Musaran Bon, j'ai finalement pensé à vérifier.
 
Effectivement, je n'ai pas copie engendrée entre l'expression return et l'appelant.
J'ai halluciné, ou c'est le service pack 5 qui a amélioré Visual C++ 6 ?
 
Je précise bien qu'il s'agit d'un retour par valeur.
 
Je ne sais plus quoi en penser, car des livres parlent bien d'une copie.
Et pas n'importe lesquels: celui de bjarne himself !
 
Mais bon, il parle aussi d'une copie dans ce cas:

Code :
  1. MonType MaVar = Montype(/*...*/);

ALors qu'il n'y en a pas.

verdoux D'ailleurs avec g++ :

Code :
  1. #include <iostream>
  2. class A {
  3.         int i;
  4.         public:
  5.         A() {i = 0;}
  6.         A(const A&) { i= 1;}
  7.         void print() { std::cout << i << "\n";}
  8. };
  9. A f() { return A();}
  10. int main () {
  11.         A a(f());
  12.         a.print();
  13.         A b(a);
  14.         b.print();
  15. }


 
Ca affiche:  

Code :
  1. 0
  2. 1

verdoux Le compilo a le droit de sauter la copie temporaire.
Et la plupart le font (g++ par exemple)
LeGreg

Willyzekid a écrit a écrit :

Ca dépend du type de la variable, non? (auto/register/static)...Par défaut, elle est détruite pour respecter les notions de bloc de déclaration.  




 
Non ca depend surtout du type de retour déclaré dans le prototype. (notamment on ne passe pas une reference ou un pointeur d'un objet alloué sur la pile)
 
LeGreg

LeGreg

musaran a écrit a écrit :

Je lis partout (et j'ai vérifié) que la valeur de retour d'une fonction subit une copie depuis l'instruction "return" vers l'appelant.




 
cette affirmation n'est pas toujours vraie
notamment quand il y a un retour par reference.
 
LeGreg

Willyzekid Ca dépend du type de la variable, non? (auto/register/static)...Par défaut, elle est détruite pour respecter les notions de bloc de déclaration.
Musaran J'ai mis des cout espions dans les fonctions d'une classe passée en valeur de retour, et j'ai constaté une construction par recopie et une destruction "en trop".
Tu me fait douter... je vais revérifier !
 
C'est clair qu'il n'y a pas besoin de savoir ça pour utiliser C++.
Mais moi j'aime bien savoir comment marchent les choses.
smaragdus

musaran a écrit a écrit :

Désolé, j'avais oublié de préciser C++.
 
C'est une question sur la façon dont les mécanismes du C++ sont implémentés.
 
Quand on fait "return expression" dans une fontion, expression est évalué en tant que variable locale temporaire, du type du retour de la fonction.
 
Ensuite, cette valeur est copiée à l'emplacement où l'appelant de cette fonction attend son résultat, et la variable locale détruite.
 




 
La valeur n'est pas recopiée : elle est pushée sur la stack, c'est pas pareil.  
 
A mon avis, tu te poses des questions qu'il est vain de se poser quand on programme dans un langage de haut-niveau.

Musaran Désolé, j'avais oublié de préciser C++.
 
C'est une question sur la façon dont les mécanismes du C++ sont implémentés.
 
Quand on fait "return expression" dans une fontion, expression est évalué en tant que variable locale temporaire, du type du retour de la fonction.
 
Ensuite, cette valeur est copiée à l'emplacement où l'appelant de cette fonction attend son résultat, et la variable locale détruite.
 
C'est là que je ne comprends pas: la fonction connaît cet emplacement, c'est l'espace de taille adéquate situé avant son premier argument dans la pile.
Alors pourquoi ne construit-elle pas cette valeur directement là pour éviter une recopie+destruction ?
 
Peut-être que je me trompe et que ça ne ce passe pas comme ça ?
 
 
Ah oui: Instance signifie objet d'une classes (ou d'un type de base en fait). C'est pour bien différencier du type lui-même.
Une variable, quoi !
 
Les fonctions à nombre d'argument variables savent toujours où se trouve leur premier argument, donc ce que je dis s'applique aussi.
HelloWorld Je comprend pas trop ce que tu veux dire ... instance ... :??:
Deja de quel langage parles-tu ?
En C, si la valeur de retour d'une fonction est un entier, elle est renvoyée via un registre (eax sur Intel).
En plus y'a le cas des fonctions à nombre de paramètres variables, genre printf (stdcall). Cette fonction ne sait pas combien de paramètres lui sont filés, donc combien sont empiles.
Musaran Je lis partout (et j'ai vérifié) que la valeur de retour d'une fonction subit une copie depuis l'instruction "return" vers l'appelant.
 
Ça ne me semble pas indispensable :
Si, avant l'appel de la fonction, une place suffisante pour son type de retour est réservée sur la pile, l'appelant et la fonction savent où trouver et  placer son instance, et il n'y a pas besoin de copie.
 
Si ce n'est pas fait ainsi, c'est sûrement qu'il y a une bonne raison, mais laquelle ?

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)