Pourquoi copier le retour d'une fonction ? [C++] - Programmation
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.
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.
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.
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.
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.
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
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
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)
Marsh Posté le 04-06-2002 à 21:39:07
D'ailleurs avec g++ :
Code :
|
Ca affiche:
Code :
|
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 :
|
ALors qu'il n'y en a pas.
Marsh Posté le 23-07-2002 à 02:13:58
J'ai compris mon erreur.
Code :
|
On peut donc faire un peu d'optimisation en construisant la valeur de retour dans l'expression du "return".
Marsh Posté le 23-07-2002 à 02:25:11
musaran a écrit a écrit : J'ai compris mon erreur.
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 ?
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)
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