first model:

class MyException
{
	string message;
public:
	MyException( string msg ): message( msg ) {};
	void printmsg() { cout<< message <<endl<<endl; }
};

void willthrow()
{
	throw MyException("mk");
}


int main(int argc, char * argv[])
{
	try
	{
		willthrow();
	}
	catch( MyException &ex)
	{
		ex.printmsg();
	}
}

second model:

class MyException
{
	string message;
public:
	MyException( string msg ): message( msg ) {};
	void printmsg() { cout<< message <<endl<<endl; }
};

void willthrow()
{
	throw new MyException("mk");
}


int main(int argc, char * argv[])
{
	try
	{
		willthrow();
	}
	catch( MyException *ex)
	{
		ex.printmsg();
                delete ex;
	}
}

it is clearly that in the second implementation the MyException object is allocated on heap, but how about the first one? What's the mecanism behind it? It would look like it's placed on the stack and then cought by reference, but how can it be placed on the stack if that is what exceptions do, unwind the stack till an apropriate catch clause is found. I mean, the stack pointer drops and when u catch the exception the reference points to an exception object above the current stack pointer... I don't know maybe i'm wrong. Can someone please explain how things actually work?

Recommended Answers

All 3 Replies

>in the second implementation the MyException object
>is allocated on heap, but how about the first one?
It's unspecified:

3 A throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively. [ Note: the temporary object created for a throw-expression that is a string literal is never of type char*, char16_t*, char32_t*, or wchar_t*; that is, the special conversions for string literals from the types “array of const char”, “array of const char16_t”, “array of const char32_t”, and “array of const wchar_t” to the types “pointer to char”, “pointer to char16_t”, “pointer to char32_t”, and “pointer to wchar_t”, respectively (4.2), are never applied to a throw-expression. —end note ] The temporary is an lvalue and is used to initialize the variable named in the matching handler (15.3). The type of the throw-expression shall not be an incomplete type, or a pointer to an incomplete type other than (possibly cv-qualified) void. Except for these restrictions and the restrictions on type matching mentioned in 15.3, the operand of throw is treated exactly as a function argument in a call (5.2.2) or the operand of a return statement.

4 The memory for the temporary copy of the exception being thrown is allocated in an unspecified way, except as noted in 3.7.3.1. The temporary persists as long as there is a handler being executed for that exception. In particular, if a handler exits by executing a throw; statement, that passes control to another handler for the same exception, so the temporary remains. When the last remaining active handler for the exception exits by any means other than throw; the temporary object is destroyed and the implementation may deallocate the memory for the temporary object; any such deallocation is done in an unspecified way. The destruction occurs immediately after the destruction of the object declared in the exception-declaration in the handler.

Anything more detailed than that depends heavily on a specific implementation, so you'll need to choose a compiler you want details for.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.