[C++]Pourquoi copier le retour d'une fonction ?

Pourquoi copier le retour d'une fonction ? [C++] - Programmation

Marsh Posté le 03-06-2002 à 12:54:51    

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 ?


Message édité par Musaran le 06-04-2002 à 10:44:40

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 03-06-2002 à 12:54:51   

Reply

Marsh Posté le 03-06-2002 à 16:33:15    

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.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 04-06-2002 à 11:00:46    

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.


Message édité par Musaran le 06-04-2002 à 11:01:02

---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 04-06-2002 à 11:11:01    

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.

Reply

Marsh Posté le 04-06-2002 à 18:26:44    

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.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 04-06-2002 à 19:10:12    

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.


Message édité par Willyzekid le 06-04-2002 à 19:11:31

---------------
Horizon pas Net, reste à la buvette!!
Reply

Marsh Posté le 04-06-2002 à 19:28:15    

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

Reply

Marsh Posté le 04-06-2002 à 19:29:42    

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

Reply

Marsh Posté le 04-06-2002 à 21:09:12    

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

Reply

Marsh Posté le 04-06-2002 à 21:39:07    

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

Reply

Marsh Posté le 04-06-2002 à 21:39:07   

Reply

Marsh Posté le 07-07-2002 à 03:16:59    

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.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 23-07-2002 à 02:13:58    

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".


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 23-07-2002 à 02:25:11    

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 ?

Reply

Marsh Posté le 24-07-2002 à 00:37:07    

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)


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed