Archived

This topic is now archived and is closed to further replies.

Fma

Error handling in C++??

Recommended Posts

In VB6 I use the following procedure for error handling: On Error Resume Next //Disabling error messages //Then I check for errors this way If Err.Number<>0 Then If Err.Number=”something” Then “Do something” End If . . End If //Then I use “On Error Goto 0” to disable “On Error Resume Next” like this On Error Goto 0 What is the equivalent to that procedure in C++, or is there a better why to do it??? Thanks for any help Edited by - fma on December 31, 2001 2:38:11 AM

Share this post


Link to post
Share on other sites
In regular c alot of functions will use a return value to notify you if an error occured. The documentation will tell you what value is pass and what values are fail depending on the error that occured internally.

In c++ you have what is called exception handling. It''s kinda like the VB On Error Goto. But more powerfull... Ppl will have to elaborate this more because am from JAVA and have a bit easier with exceptions then with C++

Share this post


Link to post
Share on other sites
Just a side note, but I find it easy and convient to implement my own error handling. That way, you can get very detailed as to what the problem is, and maybe even be able to handle it while you''re running the program! Really, it''s done me a lot of good, but sometimes it does not work.

Share this post


Link to post
Share on other sites
I used to program VB6 and still does from time to time. I am now developing software in VC++ and have made a simple singleton class that all other classes can access. The class takes care of writing errors to a logfile that I can inspect to find otherwise hard to find bugs. It has helped me a lot since.

Since it is only reacting to non fatal errors there will be a need to implement try,catch, throw etc later on. For development this works great.

for more details and other suggestions see:

http://www.gamedev.net/community/forums/topic.asp?topic_id=72741



I am actually a Swede, living in paradise.

Share this post


Link to post
Share on other sites
Thanks guys

But I’m talking about errors that crashes the program like dividing by zero, for example in VB6 if I try to delete a file by using the “kill()” function but somehow the file does not exist or the path is not correct the program simply crash so what I do is like this:

On Error Resume Next

Kill (“Path & File Name”)

If Error. Number <> 0 Then
// the program goes here if an error has occurred and

//Displays a message with the error number.

MsgBox Error. Number
End If

On Error Goto 0

That why I avoid crashing the program and I still know what error has occurred. Now, I would like to use that technique in C++ if it is possible, or if there is a beater technique then please point me out.

Thanks

Share this post


Link to post
Share on other sites
I think that divide by zero is a hardware exception , and so if you want to trap that when it occurs you would have to use Windows SEH. It is proprietary and IMO messy, but it is fast. There is an excellent tutorial on it here at GDNet; just look in the articles section.

C++ exception handling handles software exceptions , which are exceptions that your program generates. Most software that you will use with your C++ program does not take advantage of exception-handling, and it will return error codes, which you must check to determine whether an error has occurred.

Example:

HANDLE hFile = CreateFile(...);
 
// The docs for this function say that it will return INVALID_FILE_HANDLE on error
 
if( hFile == INVALID_FILE_HANDLE )
{
// TODO: get error information, and jump to handler if desired
}


I wrap each resource type inside its own class, and have the owning class manage the resource and throw exceptions when something goes wrong. The other way to handle errors is by error code return chains, which are frustrating, messy, and bad design.

Example:

bool function1a();
bool function 1b();
bool function 1c();
 
bool function1()
{
if( !function1a() )
return false;
 
if( error_condition_1 )
return false;
 
if( !function1b() )
return false;
 
if( error_condition_2 )
return false;
 
if( !function1c() )
return false;
 
// ...
 
return true; // must have succeeded
}

bool function2()
{
if( !function1() )
return false;
 
if( error_condition_1 )
return false;
 
if( !function1a() )
return false;
 
if( error_condition_2 )
return false;
 
return true;
}


...because not only do you have to check the error conditions inside the function that could cause the code to fail, you must also check each function to make sure that it has not failed.

C++ exception handling functions similarly in principle, but does not require the extra conditional logic of checking each function. C++ assumes that each function will succeed (the common case), but allows you to interrupt program flow by throwing an exception if some condition exists whereby your program cannot run normally (i.e., a resource file is corrupt).

The above example rewritten with code that uses C++ exception handling reduces to the following:

void function1a();
void function1b();
void function1c();
 
void function1()
{
function1a();
 
if( error_condition_1 )
throw exception();
 
function1b();
 
if( error_condition_2 )
throw exception();
 
function1c();
 
if( error_condition_3 )
throw exception();
 
// no need to return a code, because we assume success
}
 
void function2()
{
function1();
 
if( error_condition_1 )
throw exception();
 
function1a();
 
if( error_condition_2 )
throw exception();
 
// again, no need to return a code;
}


Throwing an exception in C++ causes the code to branch to a special compiler-generated handler which checks for the existance of an appropriate catch handler within the function that threw the exception. If none is found, the function "returns" and its local objects go out of scope, which means that their destructors will be called and any dynamically allocated resources that they used (i.e, heap memory, COM objects) will be destroyed (assuming that you wrote your destructors properly ).

The compiler-generated handler continues looking at the function's caller, and if no appropriate catch handler is found, then its local objects go out of scope, which means again that their destructors are called. This process continues until either the compiler-generated handler finds an appropriate catch handler, or it goes past main() and the program exits. If the compiler-generated handler finds an appropriate catch handler before jumping out of main() then it will transfer control to you.

C++ exception-handling has the following benefits over return value chains:

1. It forces the exception to be handled or the program to exit. This is good; you do not want errors going undetected and causing other errors in some obscure and logically unrelated section of code.

2. It is much cleaner. With exceptions you must still check error conditions and throw exceptions; however, you do not have to surround every function call with some kind of error-handling logic, and return values are free for returning data , not error codes.

3. It better segregates code. Normal code is written normally, cleanup code is placed in destructors, and exception-handling code is placed with catch handlers. If you mix all of that into one big linear function then you are bound to introduce errors.

Edited by - null_pointer on December 31, 2001 8:45:15 AM

Share this post


Link to post
Share on other sites
4. If you use stack-allocated objects or stack wrappers for dynamic objects (e.g. std::vector, std::auto_ptr), a thrown exception automatically cleans up memory and calls destructor.

Share this post


Link to post
Share on other sites
Stoffel:

The comparison was with return value chains, which also call the destructors.

Example:

  
bool function()
{
sometype stackobject;
 
if( error_condition ) return false;
 
// if error_condition is true then returning destroys stackobject

 
// ...

 
return true;
}


   
bool function()
{
sometype stackobject;
 
if( error_condition ) throw exception();
 
// if error_condition is true then throwing destroys stackobject

 
// ...

}


You are correct, though, in saying that destructors are great when used in conjunction with exceptions.

Edited by - null_pointer on December 31, 2001 5:49:05 PM

Share this post


Link to post
Share on other sites