catch(...) doesn't catch everything

A

Adam

I was looking for a way to just catch any exception throw. Given the
postings, it looks like catch(...) should do it, except it doesn't.
Maybe C++ is suppose to work this way, or maybe this is a bug in g++.

I have a small program to demonstrate below. I compiled on a RH9
system using g++ v3.4.5.

#include <iostream>

main()
{
try {
throw(1);
} catch (...) {
std::cerr << "Caught integer exception\n";
}

try {
throw;
} catch (...) {
std::cerr << "Caught exception\n";
}
}

The first exception is caught when an integer is thrown. The second
one isn't caught.

I just need to capture an exception because of a possible error in a
constructor (so I can't pass back an error code). I don't need to send
any information in the exception, so I was just using throw without any
arguments. Looks like I'll need to send something just so it works
unless I'm doing something wrong.
 
R

red floyd

Adam said:
I was looking for a way to just catch any exception throw. Given the
postings, it looks like catch(...) should do it, except it doesn't.
Maybe C++ is suppose to work this way, or maybe this is a bug in g++.

I have a small program to demonstrate below. I compiled on a RH9
system using g++ v3.4.5.

#include <iostream>

main()
{
try {
throw(1);
} catch (...) {
std::cerr << "Caught integer exception\n";
}

try {
throw;
} catch (...) {
std::cerr << "Caught exception\n";
}
}

The first exception is caught when an integer is thrown. The second
one isn't caught.

I just need to capture an exception because of a possible error in a
constructor (so I can't pass back an error code). I don't need to send
any information in the exception, so I was just using throw without any
arguments. Looks like I'll need to send something just so it works
unless I'm doing something wrong.

to be honest, I'm surprised that the second one even compiled. The
argumentless version of throw is for use inside a catch clause, to
rethrow the caught exception.
 
R

red floyd

Adam said:
I was looking for a way to just catch any exception throw. Given the
postings, it looks like catch(...) should do it, except it doesn't.
Maybe C++ is suppose to work this way, or maybe this is a bug in g++.

I have a small program to demonstrate below. I compiled on a RH9
system using g++ v3.4.5.

#include <iostream>

main()
{
try {
throw(1);
} catch (...) {
std::cerr << "Caught integer exception\n";
}

try {
throw;
} catch (...) {
std::cerr << "Caught exception\n";
}
}

Actually, on further review, your code is behaving properly.

Standard, 15.1/8 "If no exception is presently being handled, executing
a throw-expression with no operand calls terminate(). Since your second
throw is not in an exception handler (catch clause), your program calls
terminate(). Go to terminate(), go directly to terminate(), do not pass
GO, do not collect $200.
 
R

red floyd

red said:
Actually, on further review, your code is behaving properly.

Standard, 15.1/8 "If no exception is presently being handled, executing
a throw-expression with no operand calls terminate(). Since your second
throw is not in an exception handler (catch clause), your program calls
terminate(). Go to terminate(), go directly to terminate(), do not pass
GO, do not collect $200.

Damn. Missed a close quote. The quote from the Standard ends before
the word "Since". So the text should read '... operand calls
terminate()."' Everything from "Since your second..." is my commentary.
 
M

Marcus Kwok

Adam said:
I was looking for a way to just catch any exception throw. Given the
postings, it looks like catch(...) should do it, except it doesn't.
Maybe C++ is suppose to work this way, or maybe this is a bug in g++.

I have a small program to demonstrate below. I compiled on a RH9
system using g++ v3.4.5.

#include <iostream>

main()
{
try {
throw(1);
} catch (...) {
std::cerr << "Caught integer exception\n";
}

try {
throw;
} catch (...) {
std::cerr << "Caught exception\n";
}
}

The first exception is caught when an integer is thrown. The second
one isn't caught.

I just need to capture an exception because of a possible error in a
constructor (so I can't pass back an error code). I don't need to send
any information in the exception, so I was just using throw without any
arguments. Looks like I'll need to send something just so it works
unless I'm doing something wrong.

IIRC, throw with no arguments will simply re-throw the current
exception; it is usually used in cases that need to perform local
cleanup before propagating the exception further up the stack. In the
second case, there is no current exception, so nothing is thrown.
 
R

red floyd

IIRC, throw with no arguments will simply re-throw the current
exception; it is usually used in cases that need to perform local
cleanup before propagating the exception further up the stack. In the
second case, there is no current exception, so nothing is thrown.

In the second case, terminate() is called (15.1/8).
 
M

Marek Vondrak

main()
to be honest, I'm surprised that the second one even compiled. The
argumentless version of throw is for use inside a catch clause, to rethrow
the caught exception.

Yes, but the question of whether "throw;" is being invoked in the context of
a catch block can not be generally decided in the compile time. Consider the
following example:

void f()
{
throw; // (1)
}

void g()
{
try { throw 1; } catch ( ... ) { f(); } // (2)
}

When the compiler generates code for (1), it can not issue a diagnostic
because "throw;" is perfectly valid when it is called from a catch block, as
in (2). Therefore, the actual behaviour depends on the current execution
path of the program and is determined in the run time.

Regards
Marek
 
A

Adam

Standard, 15.1/8 "If no exception is presently being handled, executing
Damn. Missed a close quote. The quote from the Standard ends before
the word "Since". So the text should read '... operand calls
terminate()."' Everything from "Since your second..." is my commentary.

Thanks for the information. Now I understand why the code acts like it
does. Guess I'll just have to give an argument to throw to catch it.
 
R

red floyd

Marek said:
Yes, but the question of whether "throw;" is being invoked in the context of
a catch block can not be generally decided in the compile time. Consider the
following example:

void f()
{
throw; // (1)
}

void g()
{
try { throw 1; } catch ( ... ) { f(); } // (2)
}

When the compiler generates code for (1), it can not issue a diagnostic
because "throw;" is perfectly valid when it is called from a catch block, as
in (2). Therefore, the actual behaviour depends on the current execution
path of the program and is determined in the run time.
Good point. "throw;" not in a catch block, should compile. I guess
that's what 15.1/8 is for.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top