Skip to main content
gamedev.net
🔒 Locked

Exceptions

Started by _Sigma Mar 13, 2007 at 11:46 PM 3 replies 800+ views
Original Post
_Sigma
_Sigma
Just boning up on my C++, and as such am relearning exceptions (after being muddled up by Java's...). Two quick questions(I haven't actually tried #1, but just because it works, doesn't make it right, so the question still stands): 1. Is there any reason this is bad? (assuming TException is a defined class that takes std::string as a constructor param, etc)

void foo()
{
    if(!bar())
       throw( new TException("Error has occured"));

}

void bar()
{
    try
    {
       foo();
    }
    catch(TException &e)
    {
       cout <<  e.getString() << endl;

    }
}

2. If a function does throw, what should the functions return type be? Currently all my functions return a TRESULT which is just a typedef'd unsigned int. So T_OK is 0x1 etc. Then I am just testing for all these return codes. UGLY. Right, so should I keep the return values and just throw when bad things happen or should I change them into voids?

TRESULT foo()
{
if(! blah)
   throw(new TException("error"));
return T_OK;
}

or

void foo()
{
if(! blah)
   throw(new TException("error"));

}

any guidance would be much appreciated
Julian90
Julian90
0. Dont allocate exceptions with new just do
void foo(){    if(!bar())       throw TException("Error has occured");}
1. Its not bad per say but it will recurse infinatly since foo will never get a chance to throw its exception.

2. return whatever it makes sense to return. (i know so ambigious :) )
// examplesfloat inverse(float val){    if (val > -0.00001f || val < 0.000001f)    {        throw std::logic_error("Cannot Divide by 0");    }    return 1.0f / val;}void dostuff(int i){    if (i > 12)    {        throw std::logic_error("are you sure?");    }    my_vec += i;}
Hodgman
Hodgman
you seem to be mixing two different error handling techniques with #2.

You should either use exceptions to handle errors, OR, use an OK/FAIL return code.
There is no need to use both.
E.g. in foo() if the exception gets thrown, you dont get a chance to check the return code anyway, so the return code is always going to be OK. Foo may as well just be a void function.

TRESULT foo(){if(! blah)   return T_FAIL;return T_OK;}

OR
void foo(){if(! blah)      throw TException("error");return;}
Zahlman
Zahlman
0) Please, lose the Hungarian notation.

1) Don't allocate the exception with new. The memory for the object would leak if the catcher didn't delete it, and that's just an unnecessary headache. Further, the return type from new would be a pointer, so you'd have to catch Exception* instead. Normally, you should throw on the stack and catch by reference, yes.

And yes, that recursion is *highly* suspect.

2) Don't return things that duplicate the information encoded by the exception. As a rule of thumb, if the return value for a non-exceptional run would always be the same, get rid of it.

But otherwise, use the return value for whatever you would normally use it for instead of an error code - i.e. the kinds of purposes it was intended for and which get displaced by error codes - i.e., *the calculated result of computations in the function* (if any).
_Sigma
_Sigma
Alright thanks. I worried that something was amiss with #1.

And with #2, that is why I asked, as it did seem as if I was mixing. I think this answers my questions.

Thanks!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.