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.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Jean-Marc Bourguet
Benoit Dejean writes:
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)
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
Foo g() { cout << "ng()n"; return Foo(42); }
Même chose
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
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
donne sur mon systeme (linux, g++ 3.3.1)
On voit que g++ implémente les deux optimisations
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
Benoit Dejean <bnet@ifrance.com> writes:
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)
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
Foo g()
{
cout << "ng()n";
return Foo(42);
}
Même chose
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
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
donne sur mon systeme (linux, g++ 3.3.1)
On voit que g++ implémente les deux optimisations
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
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)
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
Foo g() { cout << "ng()n"; return Foo(42); }
Même chose
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
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
donne sur mon systeme (linux, g++ 3.3.1)
On voit que g++ implémente les deux optimisations
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