 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Benoit Dejean Guest
|
Posted: Fri Jul 25, 2003 10:31 pm Post subject: retour de fonction, copie d'agument |
|
|
je me pose des questions sur les retours de fonction et les copies
(désolé pour le volume)
#include <iostream>
using namespace std;
class Foo
{
public:
Foo()
{
cout << "Foo()t"
<< "this = " << this
<< endl;
}
Foo(int i)
{
cout << "Foo(int)t"
<< "this = " << this
<< endl;
}
Foo(const Foo &other)
{
cout << "Foo(Foo)t"
<< "this = " << this
<< " other = " << &other
<< endl;
}
~Foo()
{
cout << "~Foo()t"
<< "this = " << this
<< endl;
}
Foo& operator=(const Foo &other)
{
cout << "opertor=(Foo)t"
<< "this = " << this
<< " other = " << &other
<< endl;
return *this;
}
};
Foo f()
{
cout << "nf()n";
return Foo();
}
Foo g()
{
cout << "ng()n";
return Foo(42);
}
Foo h()
{
cout << "nh()n";
Foo tmp;
return tmp;
}
Foo i()
{
cout << "nh()n";
Foo tmp;
return Foo(tmp);
}
int main()
{
Foo res;
res=f();
res=g();
res=h();
res=i();
}
donne sur mon systeme (linux, g++ 3.3.1)
Foo() this = 0xbffffc30
f()
Foo() this = 0xbffffc20
opertor=(Foo) this = 0xbffffc30 other = 0xbffffc20 ~Foo() this =
0xbffffc20
g()
Foo(int) this = 0xbffffc20
opertor=(Foo) this = 0xbffffc30 other = 0xbffffc20 ~Foo() this =
0xbffffc20
h()
Foo() this = 0xbffffc20
opertor=(Foo) this = 0xbffffc30 other = 0xbffffc20 ~Foo() this =
0xbffffc20
h()
Foo() this = 0xbffffbe0
Foo(Foo) this = 0xbffffc20 other = 0xbffffbe0 ~Foo() this =
0xbffffbe0
opertor=(Foo) this = 0xbffffc30 other = 0xbffffc20 ~Foo() this =
0xbffffc20
~Foo() this = 0xbffffc30
avec VC7, la trace de h() donne
h()
Foo() this = 0012FEB0
Foo(Foo) this = 0012FED7 other = 0012FEB0 ~Foo() this = 0012FEB0
opertor=(Foo) this = 0012FED8 other = 0012FED7 ~Foo() this = 0012FED7
~Foo() this = 0012FED8
c'est à dire qu'il y a un recopie supplémentaire.
vous pouvez m'éclairez sur le comportement de la norme? par ce que j'ai
écrit plein de chose pour réduire le nombre d'objet temporaire dans mes
expressions, et avec VC7, le résultat est catastrophique dans certains
cas, c'est à dire pire qu'avec le comportement par défaut (c'est à dire
sans toutes mes acrobaties)
--
"Ne perdez pas de vue qu'un programme rapide
et incorrect est d'une utilité presque nulle."
Ce qui est loin d'être incompatible avec la notion d'Art.
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Sat Jul 26, 2003 6:17 am Post subject: Re: retour de fonction, copie d'agument |
|
|
Benoit Dejean <bnet (AT) ifrance (DOT) com> writes:
| Quote: | je me pose des questions sur les retours de fonction et les copies
|
Il y a deux choses à considérer: le comportement logique et les
optimisations permises par la norme.
Le comportement logique c'est que le retour de fonction utilise le
constructeur de copie.
Les optimisations permises sont au nombres de deux:
- en toute circonstance (donc pas uniquement au retour d'une
fonction), quand un constructeur de copie devrait être appelé
pour copier un temporaire, le compilateur peut utiliser le
temporaire à la place (ou plus vraissemblablement contruire
directement le temporaire)
- lorsqu'on retourne un objet nommé d'une fonction, on peut
utiliser l'objet plutôt que d'en faire une copie (NRVO) (ou plus
vraissemblablement mettre l'objet nommé directement à l'endroit
ou la valeur de retour de la fonction est attendu, donc même si
la norme le permet, je doute qu'un compilateur utilise la NRVO
quand dans des chemins différents on retourne des objets nommés
différents sauf dans des cas particuliers -- voir ci-dessus)
| Quote: | Foo f()
{
cout << "nf()n";
return Foo();
}
|
On retourne un temporaire:
construction du temporaire
construction de la valeur retournée par copie du temporaire
(peut être supprimée en construisant le temporaire directement en
tant que valeur retournée)
donc 0 ou 1 copie
| Quote: | Foo g()
{
cout << "ng()n";
return Foo(42);
}
|
Même chose
| Quote: | Foo h()
{
cout << "nh()n";
Foo tmp;
return tmp;
}
|
On retourne une valeur nommée:
construction de la valuer
construction de la valeur retournée par copie de la valeur nommée
(peut être supprimée en construisant la valeur nommée directement en
tant que valeur retournée)
donc 0 ou 1 copie
| Quote: | Foo i()
{
cout << "nh()n";
Foo tmp;
return Foo(tmp);
}
|
On retourne un temporaire construit à partir d'une valeur nommée.
construction de la valeur nommée
construction du temporaire par copie de la valeur nommée
construction de la valeur retournée par copie du temporaire
(peut être supprimée en construisant le temporaire directement en
tant que valeur retournée)
donc 1 ou 2 copies
| Quote: | donne sur mon systeme (linux, g++ 3.3.1)
|
On voit que g++ implémente les deux optimisations
| Quote: | avec VC7, la trace de h() donne
h()
Foo() this = 0012FEB0
Foo(Foo) this = 0012FED7 other = 0012FEB0 ~Foo() this = 0012FEB0
opertor=(Foo) this = 0012FED8 other = 0012FED7 ~Foo() this = 0012FED7
~Foo() this = 0012FED8
|
et que VC7 n'a pas le NRVO
A propos de ma remarque sur les objets différents, dans ce cas
Foo nrvo(bool b) {
if (b) {
Foo res1;
return res1;
} else {
Foo res2;
return res2;
}
}
rien n'empèche l'application du nrvo (on retourne des objets
différents mais il n'y a pas de problème de destruction car l'autre
objet ne doit pas être détruit), pourtant ni gcc 3.3 ni como ne le
font pas alors qu'ils le font pour
Foo nrvo(bool b) {
Foo res1;
if (b) {
return res1;
} else {
return res1;
}
}
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|