C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

throw und tempor344re objekten ^

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Babak Pourat
Guest





PostPosted: Wed Feb 09, 2005 10:38 am    Post subject: throw und tempor344re objekten ^ Reply with quote



Hallo,

Ich war einiger massen überrast als ich festgetellt habe, dass mein Compiler
für das Werfen der folgenden Exception temporären Code erzeugt.

Beispiel:

#include <iostream>

class TstException{
public:
TstException(){std::cout << "ctor" << 'n';};
TstException(const TstException & ex){std::cout << "copy ctor" <<
'n';};
~TstException(){std::cout << "dtor" << 'n';}
};

int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:

1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Warum macht er dass?

Ist die einzige Methode das zu vermeiden "throw TstException()"?
Das Blöde daran wär, dass die Exception um die es Mir eigentlich geht im
moment im Konstruktor nicht vollständig gebaut wird!

Babak

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Robert Semmering
Guest





PostPosted: Wed Feb 09, 2005 10:55 am    Post subject: Re: throw und temporäre objekte Reply with quote




Quote:

Warum macht er dass?

Weil du eine lokale Variable (auf dem Stack) deklariert und
initialisiert hast. Wenn durch die Exception ein 'Stack unwind'
passiert, dann gibt es diesen Stackteil/das Objekt nicht mehr. ERgo muss
der Compiler ein Temporal erzeugen.

Vermeiden (aber wohl auch nicht compilieren) kannst du es, wenn du dem
copy-ctor ein explicit vorstellst.
Quote:

Ist die einzige Methode das zu vermeiden "throw TstException()"?
Das Blöde daran wär, dass die Exception um die es Mir eigentlich geht im
moment im Konstruktor nicht vollständig gebaut wird!

Babak


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Wed Feb 09, 2005 10:57 am    Post subject: Re: throw und temporäre objekte Reply with quote



Babak Pourat wrote:

Quote:
Hallo,

Ich war einiger massen überrast als ich festgetellt habe, dass mein
Compiler für das Werfen der folgenden Exception temporären Code erzeugt.

Was meinst du mit "temporären Code"?

Quote:
Beispiel:

#include
class TstException{
public:
TstException(){std::cout << "ctor" << 'n';};
TstException(const TstException & ex){std::cout << "copy ctor"
'n';};
~TstException(){std::cout << "dtor" << 'n';}
};

int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:

1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Warum macht er dass?

Was? Meinst du das Kopieren des Exception-Objekts? Prinzipiell kann der
Compiler eine Exception zwischen dem Werfen und dem Fangen (unter Umständen
mehrmals) kopieren, ohne dafür eine Rechtfertigung zu brauchen. Warum ist
das ein Problem?
Im gegebenen Fall würde ich sagen, daß es daran liegt, daß das Objekt im
try-Block lokal angelegt wurde und beim Verlassen dieses Blocks zerstört
wird. Es muß also vorher kopiert werden, sonst wäre nichts mehr zum Fangen
da.

Quote:
Ist die einzige Methode das zu vermeiden "throw TstException()"?

Es gibt keine Möglichkeit, das allgemein zu vermeiden.

Quote:
Das Blöde daran wär, dass die Exception um die es Mir eigentlich geht im
moment im Konstruktor nicht vollständig gebaut wird!

Klingt nicht so arg elegant.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Falk Tannhäuser
Guest





PostPosted: Wed Feb 09, 2005 10:58 am    Post subject: Re: throw und temporäre objekte Reply with quote

Babak Pourat wrote:
Quote:
int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:
1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Normal - aException ist ja eine lokale Variable und der Block,
in dem sie lebt, wird durch das 'throw' verlassen, während
die geworfene Ausnahme ja weiterleben muss.

Quote:
Ist die einzige Methode das zu vermeiden "throw TstException()"?

Das kann die Kopie vermeiden, muss sie aber nicht - hängt davon ab, wie
gut der Compiler optimiert. Siehe § 15.1/5.

Quote:
Das Blöde daran wär, dass die Exception um die es Mir eigentlich geht im
moment im Konstruktor nicht vollständig gebaut wird!

Ist die Kopie denn wirklich so schlimm?

MfG
Falk

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Wed Feb 09, 2005 11:18 am    Post subject: Re: throw und tempor344re objekten^ Reply with quote


"Babak Pourat" <pourat (AT) autronic (DOT) melchers.de> schrieb im Newsbeitrag
news:36u7h3F589tnaU1 (AT) individual (DOT) net...
Quote:
Hallo,

Ich war einiger massen überrast als ich festgetellt habe, dass mein
Compiler
für das Werfen der folgenden Exception temporären Code erzeugt.

Beispiel:

#include
class TstException{
public:
TstException(){std::cout << "ctor" << 'n';};
TstException(const TstException & ex){std::cout << "copy ctor"
'n';};
~TstException(){std::cout << "dtor" << 'n';}
};

int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:

1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Warum macht er dass?


Weil es vollkommen legal ist. Eine throw-expression konstruiert ein
temporäres Objekt in einem gesicherten Speicherbereich. Dem Compiler ist
zwar gestattet, das temporäre Objekt auszulassen. Verpflichtet ist er aber
nicht. Gerade beim Werfen eines am stack vor der throw-expression
existierenden Objektes würde ich mir keine allzu großen Hoffnungen machen,
das temporäre Objekt wegzuoptimieren.


Quote:
Ist die einzige Methode das zu vermeiden "throw TstException()"?


Theoretisch nicht, praktisch ist das sicher besser.


Quote:
Das Blöde daran wär, dass die Exception um die es Mir eigentlich geht im
moment im Konstruktor nicht vollständig gebaut wird!


Schlecht - andererseits sollten exception-Objekte generell eher light-weight
sein. Wie schaut denn diese Klasse aus?


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Wed Feb 09, 2005 12:15 pm    Post subject: Re: throw und temporäre objekte Reply with quote

Thomas Mang wrote:

Quote:
#include
class TstException{
public:
TstException(){std::cout << "ctor" << 'n';};
TstException(const TstException & ex){std::cout << "copy ctor"
'n';};
~TstException(){std::cout << "dtor" << 'n';}
};

int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:

1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Warum macht er dass?


Weil es vollkommen legal ist. Eine throw-expression konstruiert ein
temporäres Objekt in einem gesicherten Speicherbereich. Dem Compiler ist
zwar gestattet, das temporäre Objekt auszulassen.

Bist du dir da sicher? Immerhin haben wir hier eine lokale Variable, und die
_muß_ meines Wissens beim Verlassen des Blocks zerstört werden, was aber
bedeuten würde, daß für das Werfen eine Kopie zwingend eforderlich wäre.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Babak Pourat
Guest





PostPosted: Wed Feb 09, 2005 12:21 pm    Post subject: Re: throw und tempor344re objekten^ Reply with quote

Quote:
Das Blöde daran wär, dass die Exception um die es Mir eigentlich
geht im moment im Konstruktor nicht vollständig gebaut wird!


Schlecht - andererseits sollten exception-Objekte generell eher
light-weight sein. Wie schaut denn diese Klasse aus?


Die Klasse hat ein "stream interface":
Eine Instanz davon wird erzeugt, mittels "stream operatoren" (z. B. << )
werden informationen hinzugefügt, dann wird sie (oder Ihre kopie) geworfen.

Ich kann natürlich die Informationen erst in ein ostringstream schreiben und
dieses dann dem Konstruktor als Argumet mitgeben. Im Ergebniss wird es sich
aber nichts schenken, ob ich den Stream oder die Exception kopiere und dann
lösche.

Jemehr ich darüber nachdenke um so weniger wichtig erscheint mir das
Problem, denn es gibt an dieser stelle keien optimierungs bedarf:
Die Instanz ist relativ klein(besteht im wesentlichen aus einem "streambuf"
objekt), und ausserdem wird die Excetion (hoffentlich) nicht häufig
geworfen.
Und sollte es doch Probleme geben werde ich den Copykonstruktor als "Swap"
implementieren.

Danke für die Antworten und Kommentare.

Babak



--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Wed Feb 09, 2005 12:42 pm    Post subject: Re: throw und temporre objekte Reply with quote


"Rolf Magnus" <ramagnus (AT) t-online (DOT) de> schrieb im Newsbeitrag
news:cucucv$lb5$00$1 (AT) news (DOT) t-online.com...
Quote:
Thomas Mang wrote:

#include <iostream

class TstException{
public:
TstException(){std::cout << "ctor" << 'n';};
TstException(const TstException & ex){std::cout << "copy ctor"
'n';};
~TstException(){std::cout << "dtor" << 'n';}
};

int main(){
try{
std::cout << "1:n";
TstException aException;
std::cout << "2:n";
throw aException;
}catch(TstException &){
std::cout << "3:n";
}
std::cout << "4:n";
}

Ausgabe:

1:
ctor
2:
copy ctor
dtor
3:
dtor
4:

Warum macht er dass?


Weil es vollkommen legal ist. Eine throw-expression konstruiert ein
temporres Objekt in einem gesicherten Speicherbereich. Dem Compiler ist
zwar gestattet, das tempor re Objekt auszulassen.

Bist du dir da sicher? Immerhin haben wir hier eine lokale Variable, und
die
_muß_ meines Wissens beim Verlassen des Blocks zerstört werden, was aber
bedeuten würde, daß für das Werfen eine Kopie zwingend eforderlich wäre.


Gemäß 15.1/3 schon - zumindest lese ich das so eindeutig. Ich kann mir
vorstellen, daß ein Compiler die lokale Variable direkt im Speicher für
geworfene exceptions anlegt, und so die Kopie umgeht. Bei NRVO wird ja auch
keine lokale Variable erstellt, sondern das Zielobjekt direkt dafür
eingesetzt.


z.b:

MyException Local;
Local.set(5);
Local.set2("Hallo");
throw Local;


Kann dann so aussehen (0x1 ist die Adresse für Ausnahmen):

MyException* NotLocal = new (reinterpret_cast NotLocal->set(5);
NotLocal->set2("Hallo");
Block verlassen (no-op - es wird nur der Zeiger "zerstört"), catch-handler
suchen.




Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Daniel Albuschat
Guest





PostPosted: Thu Feb 10, 2005 4:00 pm    Post subject: Re: throw und temporäre objekte Reply with quote

Thomas Mang wrote:

Quote:
Weil es vollkommen legal ist. Eine throw-expression konstruiert ein
temporäres Objekt in einem gesicherten Speicherbereich.

Was heisst "gesichert" hier?

MfG,
Daniel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Thu Feb 10, 2005 5:21 pm    Post subject: Re: throw und tempor344re objekten^ Reply with quote


"Daniel Albuschat" <daniel (AT) happy (DOT) viming.de> schrieb im Newsbeitrag
news:cug0e3$m3n$04$1 (AT) news (DOT) t-online.com...
Quote:
Thomas Mang wrote:

Weil es vollkommen legal ist. Eine throw-expression konstruiert ein
temporäres Objekt in einem gesicherten Speicherbereich.

Was heisst "gesichert" hier?


In einem Speicherbereich alloziiert auf eine Weise wie es die Implementation
will - also wir sollen uns nicht darum kümmern, wo das Ausnahmeobjekt
angelegt wird (frei nach dem Motto "Geht uns nichts an") - der aber
logischerweise während der Existenz des Ausnahmeobjektes zur Verfügung
steht. Das einzige was wir wissen, ist daß der Speicher nicht über eine
globale Alloziierungsfunktion angelegt wird (Sogesehen war mein Beispiel für
Rolf nicht exakt, da ich ein "normales" placement-new verwendet habe, was
nicht erlaubt ist. Die Illustration an sich sollte aber passen - das spätere
tatsächlich geworfene Ausnahmeobjekt wird nicht am stack angelegt, sondern
direkt im Zielort-speicher). Der Speicher wird implizit freigegeben, wenn
ein catch-handler nicht mit throw; endet - wie das gemacht wird, geht uns
ebenfalls nichts an.

Am stack kann das geworfene Objekt nicht verbleiben - der wird ja mit dem
Werfen der Ausnahme abgewickelt.


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.