|
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Exceptions... Fra : Klaus Petersen |
Dato : 16-12-02 08:40 |
|
Hej NG.
Hvorledes kaster man exceptions i sit program med Visual C++?
Klaus.
| |
BigFatLamer(DK) (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 16-12-02 08:46 |
|
Klaus Petersen wrote:
> Hej NG.
>
> Hvorledes kaster man exceptions i sit program med Visual C++?
>
> Klaus.
>
>
>
LIgsom i Java hvis du kender det sprog.
class CMYException {
.... kode kode kode ....
}
void throwException( ) {
throw new CMYException(); <---- Her kaster vi den op i luften...
}
void main() {
try {
}
catch( CMYException* e ) { <--- fanger din specielle exception klasse
}
catch( ... ) { <--- fanger alt andet, division by zero, null
pointer exception etc. etc.
}
}
Håber at det var svaret!
Cheers, BigFatLamer
| |
Anders Borum (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Anders Borum |
Dato : 16-12-02 09:29 |
|
"BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> skrev i en
meddelelse news:3dfd84ec$0$35828$edfadb0f@dread15.news.tele.dk...
[klip]
> void throwException( ) {
> throw new CMYException(); <---- Her kaster vi den op i luften...
> }
I C++ vil _new_ give en pointer til CMYException, så det er ofte mere
passende bare at skrive:
throw CMYException();
| |
![](/images/tree/0.gif) BigFatLamer(DK) (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 16-12-02 09:56 |
|
Anders Borum wrote:
> "BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> skrev i en
> meddelelse news:3dfd84ec$0$35828$edfadb0f@dread15.news.tele.dk...
> [klip]
>
>>void throwException( ) {
>> throw new CMYException(); <---- Her kaster vi den op i luften...
>>}
>
>
> I C++ vil _new_ give en pointer til CMYException, så det er ofte mere
> passende bare at skrive:
> throw CMYException();
>
>
>
Hvorfor?!
Fordelen som jeg ser det er at med en new bliver objektet lavet på
heap'en og ikke på stacken.
Jeg ved godt i mit tilfælde skal man huske at delete excep. efter brug,
men man undgår stack'en hvis man er i en volatil situration mht. stack'en.
Cheers, BigFatLamer
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) Igor V. Rafienko (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Igor V. Rafienko |
Dato : 16-12-02 12:32 |
|
[ bigfatlamer@[nospamplease]hotmail.com ]
[ ... ]
> Fordelen som jeg ser det er at med en new bliver objektet lavet på
> heap'en og ikke på stacken.
Og dette er en fordel fordi at ...?
> Jeg ved godt i mit tilfælde skal man huske at delete excep. efter
> brug, men man undgår stack'en hvis man er i en volatil situration
> mht. stack'en.
Eh? En annen ting, hvorfor tror du at
throw Foo();
vil lage Foo på stacken?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) ![](/images/tree/0.gif) BigFatLamer(DK) (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 16-12-02 18:29 |
|
Igor V. Rafienko wrote:
> Eh? En annen ting, hvorfor tror du at
>
> throw Foo();
>
> vil lage Foo på stacken?
>
>
>
>
>
> ivr
Det ved jeg heller ikke, men jeg ved at med new bliver det via heap'en.
Hvis du "opretter" et objekt lokalt sker det via stacken:
void mylocalfunc() {
CObject obj1; <--- bliver lavet på stacken
CObject* obj2 = new CObject(); <--- bliver lavet på heapen
throw CException( "Fejl fejl" ); <---- bliver lavet på ?????
}
Så jeg er ikke sikker på hvor CException bliver lavet, derfor benytter
jeg mig af den anden hvor jeg ved hvor den bliver laget.
Cheers, BigFatLamer(DK)
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) ![](/images/tree/0.gif) ![](/images/tree/0.gif) Igor V. Rafienko (17-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Igor V. Rafienko |
Dato : 17-12-02 16:02 |
|
[ bigfatlamer@[nospamplease]hotmail.com ]
[ ... ]
> Det ved jeg heller ikke, men jeg ved at med new bliver det via
> heap'en.
_Hvorfor_ bryr du deg om _hvor_ hukommelsen til et exception objekt
kommer ifra? Om det er stack, heap, eget område satt av til exceptions
eller noe annet spiller _ingen_ rolle.
(Og jeg skulle gjerne visst hvorfor _du_ mener det er fordelaktig å
allokere minne dynamisk i en throw).
> Hvis du "opretter" et objekt lokalt sker det via stacken:
Det trenger ikke å være tilfellet.
[ ... ]
> Så jeg er ikke sikker på hvor CException bliver lavet, derfor
> benytter jeg mig af den anden hvor jeg ved hvor den bliver laget.
Hvorfor _bryr_ du deg om det?
ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
-- pederst på irc
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) Mogens Hansen (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Mogens Hansen |
Dato : 16-12-02 19:16 |
|
"BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
news:<3dfd9527$0$133$edfadb0f@dread14.news.tele.dk>...
[8<8<8]
> Fordelen som jeg ser det er at med en new bliver objektet lavet på
> heap'en og ikke på stacken.
Med
throw CMYException
bliver exception objektet ikke lavet på stakken.
Det er et temporært objekt, der lever så længe der er en exception handler i
gang (C++ Standarden, $15.14).
Det er ikke specificeret hvor hukommelsen kommer fra - det må
implementeringen selv om.
Venlig hilsen
Mogens Hansen
| |
Mogens Hansen (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Mogens Hansen |
Dato : 16-12-02 19:15 |
|
"BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
news:<3dfd84ec$0$35828$edfadb0f@dread15.news.tele.dk>...
[8<8<8<]
> LIgsom i Java hvis du kender det sprog.
Der er mange ligheder, men det er ikke det samme.
[8<8<8<]
> class CMYException {
Det er måske en god ide at arve fra std::exception
[8<8<8<]
> void throwException( ) {
> throw new CMYException(); <---- Her kaster vi den op i luften... }
Hvorfor new i stedet for
throw CMYException
?
Hvem har ansvaret for frigive den ?
Der er forskel på C++ og Java.
[8<8<8<]
> catch( CMYException* e ) { <--- fanger din specielle exception klasse
Og så fange den med
catch(const CMyException& e)
> }
> catch( ... ) { <--- fanger alt andet, division by zero, null
> pointer exception etc. etc.
Nej.
Det fanger alle andre exception smidt med throw. F.eks.
throw 2;
throw "some error";
throw std::runtime_error("some error");
Division by zero, brug af null pointer etc. smider _ikke_ exception.
Det giver blot "undefined behaviour".
På f.eks. Intel x86 arkitekturen er der mulighed for at det giver en
processor exception - men det er noget helt andet.
Venlig hilsen
Mogens Hansen
| |
![](/images/tree/0.gif) BigFatLamer(DK) (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 16-12-02 20:35 |
|
Mogens Hansen wrote:
> "BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
> news:<3dfd84ec$0$35828$edfadb0f@dread15.news.tele.dk>...
>
> [8<8<8<]
>
>>LIgsom i Java hvis du kender det sprog.
>
>
> Der er mange ligheder, men det er ikke det samme.
>
> [8<8<8<]
>
>>class CMYException {
>
>
> Det er måske en god ide at arve fra std::exception
>
>
> [8<8<8<]
>
>>void throwException( ) {
>> throw new CMYException(); <---- Her kaster vi den op i luften... }
>
>
> Hvorfor new i stedet for
> throw CMYException
> ?
> Hvem har ansvaret for frigive den ?
> Der er forskel på C++ og Java.
>
>
> [8<8<8<]
>
>> catch( CMYException* e ) { <--- fanger din specielle exception klasse
>
>
> Og så fange den med
> catch(const CMyException& e)
>
>
>
>> }
>> catch( ... ) { <--- fanger alt andet, division by zero, null
>>pointer exception etc. etc.
>
>
> Nej.
> Det fanger alle andre exception smidt med throw. F.eks.
> throw 2;
> throw "some error";
> throw std::runtime_error("some error");
>
> Division by zero, brug af null pointer etc. smider _ikke_ exception.
> Det giver blot "undefined behaviour".
> På f.eks. Intel x86 arkitekturen er der mulighed for at det giver en
> processor exception - men det er noget helt andet.
>
> Venlig hilsen
>
> Mogens Hansen
>
>
>
Fint så lært vi også noget idag :D
Lige en tilføjelse, nedestående kode på to forskellige kompilere/platforme:
try {
strcpy( 0, "wefwef " );
}
catch( ... ) {
printf( "EXCEPTION\n" );
}
På Windows med VC v6.0 - bliver exceptionen fanget af catch( ... )
På Linux gcc v2.96 - bliver exceptionen ikke fanget (Segmentation fault)
Nu har jeg ikke lige gcc til windows, men jeg går udfra at det er endnu
en "feature" i MSVC at den lige fangere lidt ekstra...
Fra MSDN Library :
>>>>
If the exception-declaration statement is an ellipsis (...), the catch
clause handles any type of exception, including a C exception.
<<<<
Jeg siger ikke at det er reglen, da vi alle kender M$ forhold til
standarder :( Men hvis Klaus kun skal arbejde på Wintendo, kan han måske
bruge den ekstra feature.... - hvis han ellers stadig er med på tråden.
Men ellers tak for info :D
--
Cheers, BigFatLamer(DK)
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) Bjarke Dahl Ebert (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Bjarke Dahl Ebert |
Dato : 16-12-02 21:08 |
|
"BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
news:3dfe2b0c$0$217$edfadb0f@dread14.news.tele.dk...
> Lige en tilføjelse, nedestående kode på to forskellige
kompilere/platforme:
>
>
> try {
> strcpy( 0, "wefwef " );
> }
> catch( ... ) {
> printf( "EXCEPTION\n" );
> }
>
>
> På Windows med VC v6.0 - bliver exceptionen fanget af catch( ... )
> På Linux gcc v2.96 - bliver exceptionen ikke fanget (Segmentation fault)
>
> Nu har jeg ikke lige gcc til windows, men jeg går udfra at det er endnu
> en "feature" i MSVC at den lige fangere lidt ekstra...
Jep, Win32 har noget der hedder SEH - Structured Exception Handling, som er
mere lowlevel end C++. Det er en platform-ting. Det inkluderer
FPU-exceptions, access violations osv, og også bruger-exceptions (som
C++-exceptions hører under).
catch(...) fanger også sådanne SEH-exceptions.
Og er er p*sse-irriterende, for hvis man har en memory-fejl i sit program,
så opdager man det ikke altid.
> Fra MSDN Library :
> >>>>
> If the exception-declaration statement is an ellipsis (...), the catch
> clause handles any type of exception, including a C exception.
> <<<<
Ja, og som så ofte er de nogle vrøvlehoveder hos Microsoft.
Der er ikke noget der hedder "C exception".
Jeg tror de mener SEH-exception, som er en lowlevel (assembler-niveau)
win32-platform ting.
Mvh. Bjarke
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) ![](/images/tree/0.gif) BigFatLamer(DK) (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 16-12-02 21:23 |
|
Bjarke Dahl Ebert wrote:
> "BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
> news:3dfe2b0c$0$217$edfadb0f@dread14.news.tele.dk...
>
>>Lige en tilføjelse, nedestående kode på to forskellige
>
> kompilere/platforme:
>
>>
>> try {
>> strcpy( 0, "wefwef " );
>> }
>> catch( ... ) {
>> printf( "EXCEPTION\n" );
>> }
>>
>>
>>På Windows med VC v6.0 - bliver exceptionen fanget af catch( ... )
>>På Linux gcc v2.96 - bliver exceptionen ikke fanget (Segmentation fault)
>>
>>Nu har jeg ikke lige gcc til windows, men jeg går udfra at det er endnu
>>en "feature" i MSVC at den lige fangere lidt ekstra...
>
>
> Jep, Win32 har noget der hedder SEH - Structured Exception Handling, som er
> mere lowlevel end C++. Det er en platform-ting. Det inkluderer
> FPU-exceptions, access violations osv, og også bruger-exceptions (som
> C++-exceptions hører under).
> catch(...) fanger også sådanne SEH-exceptions.
> Og er er p*sse-irriterende, for hvis man har en memory-fejl i sit program,
> så opdager man det ikke altid.
>
>
>>Fra MSDN Library :
>> >>>>
>>If the exception-declaration statement is an ellipsis (...), the catch
>>clause handles any type of exception, including a C exception.
>><<<<
>
>
> Ja, og som så ofte er de nogle vrøvlehoveder hos Microsoft.
> Der er ikke noget der hedder "C exception".
> Jeg tror de mener SEH-exception, som er en lowlevel (assembler-niveau)
> win32-platform ting.
>
>
> Mvh. Bjarke
>
>
>
>
tak for info, altså på den fede måde ;)
--
Cheers, BigFatLamer(DK)
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) Mogens Hansen (16-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : Mogens Hansen |
Dato : 16-12-02 21:56 |
|
"BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
news:3dfe2b0c$0$217$edfadb0f@dread14.news.tele.dk...
[8<8<8<]
> try {
> strcpy( 0, "wefwef " );
> }
> catch( ... ) {
> printf( "EXCEPTION\n" );
> }
Så prøv følgende med Visual C++ V6.0 eller .NET:
<code>
#include <iostream>
class foo
{
public:
foo()
{ std::cout << "foo constructor" << std::endl; }
~foo()
{ std::cout << "foo destructor" << std::endl; }
};
int main()
{
try {
foo f;
throw 2;
}
catch(...) {
}
try {
foo f;
strcpy(0, "wfewfe");
}
catch(...) {
return 1;
}
return 0;
}
</code>
Kig på hvad programmet skriver:
<output>
foo constructor
foo destructor
foo constructor
</output>
Der mangler et kald til en destructor!
Du se at håndteringen af SEH i Visual C++ V6.0 (SP > 4) og Visual C++ .NET
er fundamental defekt.
(Det forekommer mig at det er rettet i Visual Studio .NET 2003 - men det kan
jeg ikke teste lige her)
Intel C++ V5.0 (og givetvis også V6.0 og V7.0) skriver i det mindste:
<output>
foo constructor
foo destructor
foo constructor
foo destructor
</output>
Bemærk iøvrigt at en hvilken opførsel er i orden i forhold til
sprog-specifikationen.
Mekanismen fanger ikke tilnærmelsesvis alle undefined behaviour.
F.eks.:
<code>
#include <iostream>
class foo
{
public:
foo()
{ std::cout << "foo constructor" << std::endl; }
~foo()
{ std::cout << "foo destructor" << std::endl; }
};
char* get_dangling_pointer()
{
char* p = new char('a');
delete p;
return p;
}
int main()
{
try {
foo f;
strcpy(get_dangling_pointer(), "wfewfe");
std::cout << "Works real fine!!!" << std::endl;
}
catch(...) {
return 1;
}
return 0;
}
</code>
giver
<output>
foo constructor
Works real fine!!!
foo destructor
</output>
Endelig er der et alvorligt problem:
Den typiske grund til at man har et program med "undefined behaviour" er at
man har overset nogle detaljer.
Derfor ved man ikke hvordan programmet er kommet til den situation, og
hvilken state det er i.
Hvordan kan man håndtere en ikke kendt tilstand - andet end ved at bringe
sig til en kendt tilstand, som f.eks. at afslutte programmet ?
Venlig hilsen
Mogens Hansen
| |
![](/images/tree/0.gif) ![](/images/tree/0.gif) ![](/images/tree/0.gif) BigFatLamer(DK) (17-12-2002)
![](/App_Themes/Normal/images/Window/Backgrounds/news.gif) | Kommentar Fra : BigFatLamer(DK) |
Dato : 17-12-02 00:27 |
|
Mogens Hansen wrote:
> "BigFatLamer(DK)" <bigfatlamer@[noSPAMplease]hotmail.com> wrote in message
> news:3dfe2b0c$0$217$edfadb0f@dread14.news.tele.dk...
>
> [8<8<8<]
>
>> try {
>> strcpy( 0, "wefwef " );
>> }
>> catch( ... ) {
>> printf( "EXCEPTION\n" );
>> }
>
>
> Så prøv følgende med Visual C++ V6.0 eller .NET:
>
> <code>
>
> #include <iostream>
>
> class foo
> {
> public:
> foo()
> { std::cout << "foo constructor" << std::endl; }
> ~foo()
> { std::cout << "foo destructor" << std::endl; }
> };
>
> int main()
> {
> try {
> foo f;
> throw 2;
> }
> catch(...) {
> }
>
>
> try {
> foo f;
> strcpy(0, "wfewfe");
> }
> catch(...) {
> return 1;
> }
>
> return 0;
> }
> </code>
>
> Kig på hvad programmet skriver:
>
> <output>
> foo constructor
> foo destructor
> foo constructor
> </output>
>
> Der mangler et kald til en destructor!
>
> Du se at håndteringen af SEH i Visual C++ V6.0 (SP > 4) og Visual C++ .NET
> er fundamental defekt.
> (Det forekommer mig at det er rettet i Visual Studio .NET 2003 - men det kan
> jeg ikke teste lige her)
>
> Intel C++ V5.0 (og givetvis også V6.0 og V7.0) skriver i det mindste:
> <output>
> foo constructor
> foo destructor
> foo constructor
> foo destructor
> </output>
>
> Bemærk iøvrigt at en hvilken opførsel er i orden i forhold til
> sprog-specifikationen.
>
> Mekanismen fanger ikke tilnærmelsesvis alle undefined behaviour.
> F.eks.:
>
> <code>
> #include <iostream>
>
> class foo
> {
> public:
> foo()
> { std::cout << "foo constructor" << std::endl; }
> ~foo()
> { std::cout << "foo destructor" << std::endl; }
> };
>
> char* get_dangling_pointer()
> {
> char* p = new char('a');
> delete p;
>
> return p;
> }
>
> int main()
> {
> try {
> foo f;
> strcpy(get_dangling_pointer(), "wfewfe");
> std::cout << "Works real fine!!!" << std::endl;
> }
> catch(...) {
> return 1;
> }
>
> return 0;
> }
> </code>
>
> giver
>
> <output>
> foo constructor
> Works real fine!!!
> foo destructor
> </output>
>
> Endelig er der et alvorligt problem:
> Den typiske grund til at man har et program med "undefined behaviour" er at
> man har overset nogle detaljer.
> Derfor ved man ikke hvordan programmet er kommet til den situation, og
> hvilken state det er i.
> Hvordan kan man håndtere en ikke kendt tilstand - andet end ved at bringe
> sig til en kendt tilstand, som f.eks. at afslutte programmet ?
>
> Venlig hilsen
>
> Mogens Hansen
>
>
Kan kan ikke implementer en "On Error Resume Next" det "virker" jo i
alle VB programmer........ just kidding....
Helt enig.....men nu er vi vist ved at bevæge os udover det oprindelige
spørgsmål.
Gud ved om Klaus P. fik svar på sit spørgsmål?????
--
Cheers, BigFatLamer(DK)
| |
|
|