• Advertisement

Archived

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

The (un-?)popularity of try, throw and catch

This topic is 6340 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was just curious how many of the game programmers on this forum use C++-style exception handling (try-throw-catch) to check their errors, as opposed to more conventional error-checking devices (returning error codes, error members in classes, etc.). Does exception handling blend well into game programming? I notice that most functions that I see posted in this forum and the API forum do not have throw() lists on the declaration, so I couldn''t help wondering if try-throw-catch was unpopular to game programmers. I haven''t made the switch yet because I''m more accustomed to returning an error code, but I can see some of the benefits, such as fewer explicit error checks (it''s really annoying to have to draw pixels with "err = DrawPixel(x,y); if (err) return err" when you can just draw them all and catch all the exceptions in separate blocks. Are there any documents or examples on using exception handling in games?

Share this post


Link to post
Share on other sites
Advertisement
Dude, check out the past featured articles section under programming. I haven''t checked, but i swear i saw something with exception handling. It was an asrticle written a while ago. Exception handling in C++ i think it was. Check it out.

==============================
\\// live long and prosper; \||/ die short and rot.
==============================

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I like to use exceptions. However I never use throw lists because for one I don''t think VC really supports them and for two I think they''r a really dumb idea. In a complex app it''s very hard to be sure exactly what exceptions might get thrown in the current code let alone for the rest of time. So people end up deriving their entire exception heirarchy from a single class and list that class in the declartion which makes it pointless anyway.

I think people don''t use exceptions for several reasons. The first is that there is a perception that they slow down your code. I have yet to see any hard data that support this in the common case - when the excpetion is *not* thrown. Secondly, exceptions require a bit of up front disipline to use correctly. You have to make sure that all resources are allocated such that the will be autmatically freed when an exception happens. Thirdly once they get started people tend to want to use exceptions for non-exceptional changes in control flow. This bad practice *does* cause performance problems which then turns them off of exceptions again. Lastly, exceptions are relatively new. Cutting and pasting old code, then going through it and making it exception friendly takes more effort than not using exceptions at all.

-Mike

Share this post


Link to post
Share on other sites
quote:

However I never use throw lists because for one I don''t think VC really supports them and for two I think they''re a really dumb idea.



I don''t use throw lists, but it''s not because VC doesn''t support them (which it doesn''t). It''s because of what happens if the wrong kind of exception gets out, the default action is to terminate the program. Even if exceptions where checked at compile time (like they should be, just like const), it means you have to change lots of code that shoudn''t care about the exceptions. e.g.


void bar() throw(my_exception)
{
//some code that can throw
}

void foo() throw(my_exception)
{
bar();
}

void goo()
{
try
{
foo();
}
catch(...)
{
//etc...
}
}


Now if bar() decided it''s to also throw my_other_exception, you also need to change foo() and the whole point of exceptions is avoid the code in between the error and the handler needing to know about the error. In real life it''s pretty likely you''d have more functions this, which means even more work for something that really doesn''t matter.

quote:

So people end up deriving their entire exception heirarchy from a single class and list that class in the declartion which makes it pointless anyway



Unlike other classes, it''s a good idea to derive all your exceptions from the same class (e.g. std::exception). It makes it easier for you add new exceptions - most code doesn''t really care what was thrown, if they are catching it. (and even more functions shouldn''t need to catch anything, as long as you use std::auto_ptr and things like). and it''s nice to be able to do something like this:


int main()
{
try
{
//rest of main
}
catch(std::exception e)
{
cerr << "Unhanded exception : " << e.what() << endl;
}

}

Share this post


Link to post
Share on other sites
The function exception specification ("throw()") is a performance hint to the compiler, similar to inline in purpose. You do not inline everything, and you do not add throw to the end of all your functions indicating what exceptions they must throw. The most common usage of throw will probably be:


inline some_fast_simple_function_that_doesn''t_call_anything_else() throw()
{ ::x += 2; } // whatever...



C++ compilers don''t optimize as well as they should. Either: 1) the compiler writers are lazy, or 2) (much more likely) the language requires lots of time/energy to optimize. C++ can be very low-level, doing bit-manipulation and such, and it can be very high-level using classes, virtual functions, etc. Providing the function exception specification syntax may help programmers optimize their code (and thus make wider use of exceptions!) while still programming on poorly optimizing compilers.

I heard it explained that functions that throw exceptions can be slower (every little bit may count, as in a pixel-plotting function ), but of course you should check that out for yourself. I would like to understand why myself...

Happy Coding!



- null_pointer
Sabre Multimedia

Share this post


Link to post
Share on other sites
2.5 cents ->
I use exceptions extensively in my DirectX-using Windows98-hosted gambling machines, and the only time I use any form of exception specification is on the member functions for the exception classes themselves, and on certain functions that cannot throw exceptions either due to being simple and self contained, or due to catching all exceptions and recovering from any situation (not too common .

I do not know what form of performance impact I pay for using exception as I have never had a version of the program running without them.

Share this post


Link to post
Share on other sites
I don''t use try/catch/throw because it''s only good for really bad errors!!!

Well, you could use it for simple "non terminal" errors. The problem is that you have to use auto_ptr stuff to prevent memory leaks!
If an exception get''s thrown out of nowhere, a lot of shit has to be freed and destroyed and uninitiated and de-allocated and...

Share this post


Link to post
Share on other sites
Sorry if this makes anybody mad as this is a question not an opinion.

lots of questions

Do all exception terminate the program?, or is that just the examples that i read.
(wrote the check(int) method as practice)
(any mistakes? )
(made in Java as well, not a C question )





say i have a "pick a number between 1-10" program
Main
calls a method "getinput" that trys to check the int by calling
check(numberentered) and it also catches the BadintException

boolean check(int i)
{
if (i != 0) {
if (i < 11) { return true;}
else { throw new BadintException(i); } // number is bigger then 11 "big no no"
}
else { throw new BadintException(i); }// number is 0 "big no no"
}





relevant to the program:
what is the best way to make the user pick another number?
I can only think of two solutions/questions 1.call getinput again from within the catch block.(is this bad programming? as in get stuck in a loop)

2.forget the exceptions and just have getinput loop until check(int) returns true? btw. what is the best way to loop in this scenario?


about a method calling itself
is there a way a method can check to see if the variable x has been made/declared?
like:

if (x != null) { ++x;}
else {int x = 0;}

if (x != null) {
if (x != 10){
"call itself again"} //tehehe
}
else {
exit somehow(doens't matter to me)}


now can this method call itself and expect x to be 1 (cause the first call didn't return so x should still be declared right? )

will a compiletime or runtime( i expect compiletime error)
happen when this method is first called? because x isn't declared and can't be referenced (as in hasn't even been set to null).
is there another operator(?) i can use to see if a variable has been declared???

even if it is allowed, is it bad coding/practice/concept?

anyhelp is of course appreciated.

Phew!...Thanks.






Edited by - CodyVa on September 2, 2000 4:16:57 AM

Edited by - CodyVa on September 2, 2000 4:22:07 AM

Share this post


Link to post
Share on other sites
try-throw-catch isn't for dealing with your own errors, its for dealing with run-time errors that will end up killing your program. It is a waste of time to use them for normal errors that you might expect e.g. improper value entered because error codes are quicker and better.

Basically, try-throw-catch is just used to catch run-time errors:

try
{
//this is saying "see if this works"
}
throw
{
//this is saying "throw this exception if it doesn't work"
{
catch
{
/*instead of having a message come up about how your programs gonna die now, you can catch the error and recover\terminate gracefully. */
}


If its just normal errors you are after this will do:


void CheckForError(int ErrorIndex)
{
if (ErrorIndex < 1 || ErrorIndex > 25)
{
ValidateError();
}
}

void ValidateError()
{
Number = LastNumber; /*say you backed up number each time it changed*/
}



etc. etc. You get the point

In the game industry I'm not sure how many people actually use it. I suspect it would have performance implications but I'm not sure on that.

Personally, I steer clear of them mostly, but I have been known to 'try' it on a few times because it can come in very handy in the right situations. Its just one more tool in the toolbox and that can't be a bad thing






Edited by - lucasdg on September 2, 2000 5:05:51 AM

Share this post


Link to post
Share on other sites
Java and C++ differ a little bit. In C++, exceptions were only meant as an ''oh crap, things are really screwed up now'' recovery or information tool. As Lucasdg mentioned, they weren''t originally meant for dealing with run of the mill errors.

With Java its a bit different. Many of the Java standard APIs use exceptions for things that are more or less just your standard error-code type stuff. Because of this, most Java code written on top of these APIs follows suits and uses lots of exception handling. In general, its not that big of a deal in Java as Java bytecode is at such a high level that the exception handling system doesn''t really add any extra time overhead when running, unlike C++ where using exception handling can dramatically alter performance.

Ditto for RTTI/Reflection which is widely used in Java and used only sparingly in C++.


Share this post


Link to post
Share on other sites
Has this changed into a purely Java question?
Java can return whatever valid type you tell it to return. If you want it to return an error code, then that''s fine. Just remember you can only return one type. Why would you want to check if a variable is declared? It''s either in the scope or not.. if you declare it in an inner block, then it''s not visible to the code outside of it. If you want to check if a certain path through your code was taken, declare some flag outside of that scope and set it within the path''s block and then check it after the block.

Exceptions are not only to catch the really bad errors. For Java programming, we make extensive use of customized exceptions at work.

Share this post


Link to post
Share on other sites
okay...that''s cool


but what''s the best way to call the same function again?

do i simple call the same function agian (to get input?)
i''m talking about best approach now..not the exceptions

Share this post


Link to post
Share on other sites
quote:

''oh crap, things are really screwed up now''


hehe

Hmmm...I don''t know much about Java error handling. I suspect its way different to C++ exception handling if you Java guys use it lots. Is it it like custom error codes and stuff?



CodyVa: Do you mean recursion? Where you call the function that your in?

Share this post


Link to post
Share on other sites
lucasdg, yup! that''s what i mean
What is an effecient way for a method to call itself and keep track of how much time it''s been called?

about java and exception! I don''t know if it''s supposed to be made for custom or only other errors, but i have plans to use it for custom errors/mistakes.

But in a book i read it uses a bank program as an example
and illegal withdrawals(more then in the account) throws an exception, I don''t know if that''s just for example or practical usage. anywho.

I made up some "junk" code i dont'' know if it will work

if (x != null) { ++x;} //if x is declared increment
else {int x = 0;} //if not declare it

if (x != null) { //check if it''s declared again
if (x != 10){ //makesure it''s not above 10, cause if it''s
//10 then it''s looped to long
"call itself again"} //tehehe
}
else {
exit somehow(doens''t matter to me)}


i know that''s very sloppy, but I want to know is if the next time the function is called will the x be 0? or not declared?
I think it won''t be declared. I think i figured a way anyway, but i don''t know if it''s usefull or practical.


somemethod(normal parameters, counter);

if (counter !=10)
{ do whatever
and if something bad happens ++counter
and call somemethod again}
else { throw WhateverException(); }

is that practical?usefull?

Share this post


Link to post
Share on other sites
Use static variable. Static variables have a lifespan of the entire program so even if your function is out of scope, the static variable still exists and still retains its value.
Here is an example of a recursive function making use of static variables.

    
void recursivefunction()
{
static int count; //count can be used as a name in the function

count++;

if (count < 10)
recursivefunction();
else
return;
}


Note that redeclaring the static int ''count'' will not change it, it simply places the name in scope.

Hope this helps...
Lucas

Share this post


Link to post
Share on other sites
Why do some of you claim VC++ doesn''t support exception specifications?

I''ve never actually tried it other than using it like, for example:

    
int Foo() throw()


to show that the function doesn''t throw.

VC++ doesn''t choke on this so why are you saying it doesn''t support exception specs?

- Dire Wolf
direwolf@digitalfiends.com

Share this post


Link to post
Share on other sites
quote:
Original post by Dire.Wolf

Why do some of you claim VC++ doesn''t support exception specifications?

I''ve never actually tried it other than using it like, for example:

        
int Foo() throw()


to show that the function doesn''t throw.

VC++ doesn''t choke on this so why are you saying it doesn''t support exception specs?

- Dire Wolf
direwolf@digitalfiends.com

If I remember correctly VC simply ignores throw() in function specification. Compiler accepts it as valid syntax but does not do anything with it.

Share this post


Link to post
Share on other sites
Go to this page in MSVC 6.0 docs:
- Visual C++ Documentation
- Using Visual C++
- Adding Program Functionality
- Details
- Exception Handling Topics (C++)
- Exception Handling Topics (C++) (yes, there are 2)
- Exception Handling Syntax

In that article, at the bottom of the page, you will find:

Microsoft Specific —>

Microsoft C++ does not support the function exception specification mechanism, as described in section 15.4 of the ANSI C++ draft.

END Microsoft Specific

Share this post


Link to post
Share on other sites
As far as I understand it, Microsoft creates their own standards if there''s any standards (regarding C# or Java ). And definitely doesn''t care for existing standards (But any compiler needs time to evolve ). In special I mean using the scope operator in a C++ class declaration which isn''t in any C++ specification

To CodyVa:

You cant''t compare a variable to a value if it is not declared and as menationed earlier you can''t access a variable outside you''re scope but the global scope.

Your code:

if (x != null) { ++x;} //if x is declared increment
else {int x = 0;} //if not declare it


For the compiler, this is like: compare the global variable x to zero and increment its value if it is so.
else declare a new variable x. Because the new variable is declared in a block, it is only valid and accesible in the block itself.

I think you can make it with a static variable, but then you should be aware to decrement the variable again when returning from the function. Because you never would be able to call the function again.

Another approach would be to use a function like this:

void func (int maxiterations)
{
if ( maxiterations > 0 )
if (somethinggoeswrong)
func(maxiterations-1);
}


Hope this helps

Share this post


Link to post
Share on other sites
Personally, I love exceptions, but you''ve really got to use them properly. First lesson is that they are NOT meant for flow-control, they''re meant for exceptional situations (thus the name). There''s a cost associated with entering a try block and percolating an exception up the stack is not as fast as normal code (which isn''t a big deal if they only happen ocasionally). Second lesson is that exception specifications are of questionable merit. The "why" is a tad involved but I would reccommend checking item 14 of Scott Meyers'' "More Effective C++": "Use exception specifications judiciously." Basically, they''re more trouble than they''re worth. Finally, never throw an exception out of a destructor. Bad Things (tm) happen (like your program crashing).

Why are exceptions so great? Instead of filling your code with error recovery routines you can centralize them. Also, rather than checking the return value of every function call, you can assume that it was successful if an exception was not thrown. This doesn''t work for every situation, but it''s nice not have to put every function call in a "if" block. Another handy way to manage things (either as an alternative to exceptions or in addition to them) is to put some error checking and recovery code in an inline function. It''s much safer than macros but expands to effectively the same thing. Something like the following:

inline void Try( int retval ) {
if( retval ) {
// something went wrong
}
}

Try( MyFunc( param1, param2 ) );

A pretty handy way to code error stuff once but use it all over. I do this in situations where I don''t want to throw exceptions or at times when I need to examine a retval a bit more closely before determining whether to throw or not (like network code where some error values actually represent a success condition).

Share this post


Link to post
Share on other sites
Shouldn''t Microsoft have to follow the ANSI\ISO C++ standards to be able to implement C++ compiler?



-=[ Lucas ]=-

Share this post


Link to post
Share on other sites
microsoft doesn''t look at standarts. another example showing this is STRUCT

normaly, the struct came from C, and doesn''t support methods, private and things like it, but in VC you could take every class, and change the word class into struct.. nothing changes, so I (started and always used VC) really don''t know, how I could programm reall C-Code in VC. Even whitout using all the C++ stuff, you don''t know if, what you use is really normal C stuff (I wont start talking about MFC)

to the exeption handling:
I never understood try catch and this, so I never used it. and my one and only thing, I use, is TRUE and FALSE.. every function returns a value, that could be TRUE and FALSE, and with only this little errorhelp, I never had problems with anything (onetime my programm got an error with the mouse and I had to re-install my complete windows, loosing all the data, but.. no, no problems)

Share this post


Link to post
Share on other sites
davepermen:
The ANSI C++ standard says that you can put functions in a struct (then they''re called methods). The only difference between a class and a C++ struct is that in a class everything is private by default, and in a struct it''s public.

And yes, Micro$oft is still allowed to make a C++ compiler without following the ANSI standard. They just can''t call it an "ANSI C++ compiler".

But to get back to the point: I do use exceptions often. I think they''re cool and easier to use than return codes. I use them more in Java than in C++, but I think that''s because in Java, you don''t have to keep track of all your memory allocations (with the garbagecollector and all), so it''s easier than in C++.

Dormeur

Share this post


Link to post
Share on other sites

  • Advertisement