X * une_fontion(void)
{
try {
return new X( f());
}
catch(...)
{
return new X();
}
}
Ma question : si f() lance une exception, est-ce que j'ai un problème de
perte de mémoire ?
je pense que les paramètres du constructeur sont évalués avant "l'appel"
proprement dit du constructeur et que l'allocation mémoire n'est pas
réalisée lorsque l'exception est levée. Mais je préfère avoir l'avis
d'experts :-)
Merci à ceux qui ne sont pas en vacances.
Marc
X * une_fontion(void) { try { return new X( f()); } catch(...) { return new X(); } }
Ma question : si f() lance une exception, est-ce que j'ai un problème de perte de mémoire ?
Non. (Sauf compilo très vieux et buggué)
je pense que les paramètres du constructeur sont évalués avant "l'appel" proprement dit du constructeur et que l'allocation mémoire n'est pas réalisée lorsque l'exception est levée.
Ceci n'est pas spécifié par la Norme et le compilateur peut faire comme bien lui semble, mais il doit se débrouiller pour que la fonction de dé-allocation soit appelée si la mémoire a déjà été allouée quand l'exception est levée (ce qu'il devra faire de toute façon si une exception est levée dans le constructeur lui-même).
Falk
Marc G schrieb:
Je m'explique
j'ai un code du genre
X * une_fontion(void)
{
try {
return new X( f());
}
catch(...)
{
return new X();
}
}
Ma question : si f() lance une exception, est-ce que j'ai un problème de
perte de mémoire ?
Non. (Sauf compilo très vieux et buggué)
je pense que les paramètres du constructeur sont évalués avant "l'appel"
proprement dit du constructeur et que l'allocation mémoire n'est pas
réalisée lorsque l'exception est levée.
Ceci n'est pas spécifié par la Norme et le compilateur peut faire comme
bien lui semble, mais il doit se débrouiller pour que la fonction de
dé-allocation soit appelée si la mémoire a déjà été allouée quand
l'exception est levée (ce qu'il devra faire de toute façon si une
exception est levée dans le constructeur lui-même).
X * une_fontion(void) { try { return new X( f()); } catch(...) { return new X(); } }
Ma question : si f() lance une exception, est-ce que j'ai un problème de perte de mémoire ?
Non. (Sauf compilo très vieux et buggué)
je pense que les paramètres du constructeur sont évalués avant "l'appel" proprement dit du constructeur et que l'allocation mémoire n'est pas réalisée lorsque l'exception est levée.
Ceci n'est pas spécifié par la Norme et le compilateur peut faire comme bien lui semble, mais il doit se débrouiller pour que la fonction de dé-allocation soit appelée si la mémoire a déjà été allouée quand l'exception est levée (ce qu'il devra faire de toute façon si une exception est levée dans le constructeur lui-même).
Falk
Marc G
Non. (Sauf compilo très vieux et buggué) C'est pas le cas, donc a priori pas de problème...
je te remercie Marc
Non. (Sauf compilo très vieux et buggué)
C'est pas le cas, donc a priori pas de problème...
qui force le constructeur (potent.t unique) à supporter un paramètre nul, évitant les plantes pour cas non prévu (et surement la redondance du code du constructeur).
Sylvain.
Alain Gaillard wrote on 26/08/2007 13:29:
Et pourquoi même se poser la question ?
En écrivant:
X * une_fontion(void){
try {
le_type_de_truc truc = f();
return new X(truc);
}
catch(...){
return new X();
}
}
tu es tranquille :)
Et AMHA le code gagne en lisibilité.
pour la lisibilité et le déterminisme, je préférerais:
qui force le constructeur (potent.t unique) à supporter un paramètre
nul, évitant les plantes pour cas non prévu (et surement la redondance
du code du constructeur).
qui force le constructeur (potent.t unique) à supporter un paramètre nul, évitant les plantes pour cas non prévu (et surement la redondance du code du constructeur).
Sylvain.
Fabien LE LEZ
On Sun, 26 Aug 2007 13:29:45 +0200, Alain Gaillard :
le_type_de_truc truc = f(); return new X(truc);
Attention, "le_type_de_truc" doit en fait être le type de retour de f(). Ça peut être un objet, une référence, ou une référence const.
On Sun, 26 Aug 2007 13:29:45 +0200, Alain Gaillard :
le_type_de_truc truc = f();
return new X(truc);
Attention, "le_type_de_truc" doit en fait être le type de retour de
f(). Ça peut être un objet, une référence, ou une référence const.
Le Mon, 27 Aug 2007 02:19:32 +0200, Fabien LE LEZ a écrit :
On Sun, 26 Aug 2007 18:39:19 +0200, Alain Gaillard :
Certes. Et alors ?
Et alors, ça complique pas mal la création du code.
Peux-tu me dire dans quelles conditions ton code est exactement équivalent au code initial ?
Je ne vois tellement pas le problème que je me demande si on parle de la même chose. Où est le problème à écrire "le_BON_type_de truc" ?
-- Alain
Mathias Gaunard
Ma question : si f() lance une exception, est-ce que j'ai un problème de perte de mémoire ?
Et pourquoi même se poser la question ? En écrivant:
X * une_fontion(void) { try { le_type_de_truc truc = f(); return new X(truc); } catch(...) { return new X(); } }
tu es tranquille :) Et AMHA le code gagne en lisibilité.
C'est beaucoup plus verbeux, ça oblige de connaître le type de retour, et ça empêche les move semantics et le perfect forwarding de marcher. Sans parler du fait qu'il faut faire attention à la portée de la variable qui détermine sa durée de vie, etc.
Bref, c'est totalement stupide.
Ma question : si f() lance une exception, est-ce que j'ai un problème de
perte de mémoire ?
Et pourquoi même se poser la question ?
En écrivant:
X * une_fontion(void)
{
try {
le_type_de_truc truc = f();
return new X(truc);
}
catch(...)
{
return new X();
}
}
tu es tranquille :)
Et AMHA le code gagne en lisibilité.
C'est beaucoup plus verbeux, ça oblige de connaître le type de retour,
et ça empêche les move semantics et le perfect forwarding de marcher.
Sans parler du fait qu'il faut faire attention à la portée de la
variable qui détermine sa durée de vie, etc.
Ma question : si f() lance une exception, est-ce que j'ai un problème de perte de mémoire ?
Et pourquoi même se poser la question ? En écrivant:
X * une_fontion(void) { try { le_type_de_truc truc = f(); return new X(truc); } catch(...) { return new X(); } }
tu es tranquille :) Et AMHA le code gagne en lisibilité.
C'est beaucoup plus verbeux, ça oblige de connaître le type de retour, et ça empêche les move semantics et le perfect forwarding de marcher. Sans parler du fait qu'il faut faire attention à la portée de la variable qui détermine sa durée de vie, etc.