Skip to main content
gamedev.net
🔒 Locked

Try this...

Started by kelaklub 6 replies 650+ views
Original Post
kelaklub
kelaklub
While I thought I knew about try and catch, this has me completely confused. What is the "throw (string)" after the function name used for, and how come in the function the catch block is doing a throw, I thought the try block did a throw.
/*! Arena constructor (four parameters)
 * In this constructor we specify the width, height, bits per pixel for the
 * display (default:16) and the SDL display flags (default: SDL_SWSURFACE). 
 * These are the exact same four parameters that one would normally pass to 
 * SDL_SetVideoMode(). 
 * Note that a whole range of potential errors could occur here; they are
 * thrown as a std::string. Make sure you handle the exception in the calling
 * code. */
Arena::Arena(int width,int height,int bpp,Uint32 flags) throw (string) 
			
{ 
	try
	{
		initScreen(width,height,bpp,flags);
		xmin=ymin=0; 
		xmax=screen->w; 
		ymax=screen->h; 
		updateWhole=overflowUpdateWhole=false; 
		font=NULL;
		nUpdateRects=0; // NEW 0.3

	}
	catch (string error)
	{
		throw;
	}
}
Zipster
Zipster
It basically tells the compiler that the function will throw a string object. This is good in cases where you explicly want to let the compiler know what's being thrown. This is a good example, because a string-literal could either be just a char*, or you could interpret it as a string object (constructed for you with the literal thrown). In most cases it isn't neccesary though. Sometimes you can do throw(), which tells the compiler a function will never throw an exception.

[edited by - Zipster on May 15, 2004 7:10:57 PM]
dcosborn
dcosborn
throw in the function definition is an exception specification. Its there to tell users of the function what exceptions they should expect the function to throw. They''re somewhat controversial so google for "c++ exception specification".

throw in the catch block is a rethrow. Its just rethrowing the same exception and letting it be caught by someone else down the chain.
kelaklub
kelaklub
Ah, thank you. Things are starting to make a lot more sense. I understand now the that the purpose of the throw in the catch block is to pass the error down a chain. But I am still not sure about the exception specification within the function definition. Is it basically just to provide information and nothing else to the user that this function may throw an error of type string? And why the controversial nature of such a syntax?
Zipster
Zipster
It explicitly tells the compiler what's being thrown, rather than having the compiler figure it out itself. Like I said in my first reply, something like "Exception text" could either be interpreted naturally as a char*, or explicitly as a string. The compiler will go with the built-in type, but if you want it to be a string, you have to explicitly say so. Otherwise, you really don't need it.

As for the syntax, it's very similar to the way Java handles exceptions:

// Java!

public void SomeFunction(int iValue) throws Exception
{
if(iValue != WHAT_I_WANT)
throw new Exception("Rawr!");
}

So the syntax isn't so foreign The only difference in Java, is that if you don't have try-catch blocks in your function, you must explicitly define what exceptions are being thrown. Basically, anytime an exception could unravel through function boundaries you need to explicitly tell Java what exceptions.

[edited by - Zipster on May 15, 2004 7:57:52 PM]
dcosborn
dcosborn
Really I''m not too clear on their pitfalls since I never use them. I assume the issue is that, if you provide a specification, you need to ensure that it is complete, and provide all possible exceptions that could be thrown from the function, or the functions that it calls. Therefore, its a lot of maintainance work and requires very careful programming. If an exception occurs that has not been listed in the spec, std::unexpected is called. If you simply don''t provide a spec, all exceptions are able to be thrown. An empty spec (ex: throw()) means that no exceptions will be thrown.

Here''s a quick tutorial I found.

Boost avoids exception specifications. Here''s their rationale.
kelaklub
kelaklub
Thanks guys. This has all been extremely informative.
markr
markr
It''s generally considered a good idea to always throw by value and catch by reference, so you have


class BaseException {
public:
// ...

virtual void print();
};

class SomeException : public BaseException {
public:
virtual void print();
};

try
{
// ...

thow SomeException("it went wrong");
} catch (BaseException &e) {
e.print();
}


So you can use polymorphism in exceptions.

One useful use for this I''ve found, is to create an exception class which handles system or library errors, and wraps them into an object which can be caught and printed.

So effectively you examine (in the constructor) errno (or GetLastError() in win32), create a message, and throw that object

Mark

Topic Locked

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

Sign in to reply to this topic.