un-catched Exceptions in mixed C/C++ code

W

wrungel

Exceptions thrown by C++ function which is called by a C-function
which is called by a C++ function are not catched by outermost C++
function.

Operating system: Linux
Compiler: GNU GCC Version 4.2.1

file x.cc:
main ()
{
try {
y_func();
} catch (...) {
cout << "This line is NOT executed if _func() is compiled with C+
+ compiler";
}
}

file y.c:
y_func()
{
z_func();
}

file z.cc:
z_func()
{
throw exception;
}


Files x.cc and z.cc are compiled with C++ (GNU) compiler.
File y.c is compiled with C (GNU) compiler.

If z_func() throws, exception is not catched by main function.
Program crashes with error message: terminate called after throwing of
an instance 'of std::exception'

If y.c is compiled with C++ (GNU) compiler, exception is catched by
main function (desired behavior).

The complete source code can be downloaded here:
http://freenet-homepage.de/wrungel/exceptions.tgz

The problem is that the y_func() comes from third-party library and
can not be recompiled with C compiler.

How can I catch exceptions in main function caused by z_func()?
 
E

Erik Wikström

Exceptions thrown by C++ function which is called by a C-function
which is called by a C++ function are not catched by outermost C++
function.

Operating system: Linux
Compiler: GNU GCC Version 4.2.1

file x.cc:
main ()
{
try {
y_func();
} catch (...) {
cout << "This line is NOT executed if _func() is compiled with C+
+ compiler";
}
}

file y.c:
y_func()
{
z_func();
}

file z.cc:
z_func()
{
throw exception;
}


Files x.cc and z.cc are compiled with C++ (GNU) compiler.
File y.c is compiled with C (GNU) compiler.

If z_func() throws, exception is not catched by main function.
Program crashes with error message: terminate called after throwing of
an instance 'of std::exception'

If y.c is compiled with C++ (GNU) compiler, exception is catched by
main function (desired behavior).

The complete source code can be downloaded here:
http://freenet-homepage.de/wrungel/exceptions.tgz

The problem is that the y_func() comes from third-party library and
can not be recompiled with C compiler.

How can I catch exceptions in main function caused by z_func()?


You have to catch the exceptions in z_func() and convert them to error
codes or something like that (setting a global flag?) and then check for
that in main().
 
K

Kira Yamato

Exceptions thrown by C++ function which is called by a C-function
which is called by a C++ function are not catched by outermost C++
function.

Operating system: Linux
Compiler: GNU GCC Version 4.2.1

file x.cc:
main ()
{
try {
y_func();
} catch (...) {
cout << "This line is NOT executed if _func() is compiled with C+
+ compiler";
}
}

file y.c:
y_func()
{
z_func();
}

file z.cc:
z_func()
{
throw exception;
}


Files x.cc and z.cc are compiled with C++ (GNU) compiler.
File y.c is compiled with C (GNU) compiler.

If z_func() throws, exception is not catched by main function.
Program crashes with error message: terminate called after throwing of
an instance 'of std::exception'

If y.c is compiled with C++ (GNU) compiler, exception is catched by
main function (desired behavior).

The complete source code can be downloaded here:
http://freenet-homepage.de/wrungel/exceptions.tgz

The problem is that the y_func() comes from third-party library and
can not be recompiled with C compiler.

How can I catch exceptions in main function caused by z_func()?

How did you get the linker to be able to let the C translation unit
(y.c) see the C++ function in the C++ translation unit (z.cc)?

Sorry that I couldn't refer to your source code. My Mac cannot
recognize the gtar format.
 
A

Abhishek Padmanabh

Exceptions thrown by C++ function which is called by a C-function
which is called by a C++ function are not catched by outermost C++
function.

Operating system: Linux
Compiler: GNU GCC Version 4.2.1

file x.cc:
main ()
{
try {
y_func();
} catch (...) {
cout << "This line is NOT executed if _func() is compiled with C+
+ compiler";
}

}

file y.c:
y_func()
{
z_func();

}

file z.cc:
z_func()
{
throw exception;

}

Files x.cc and z.cc are compiled with C++ (GNU) compiler.
File y.c is compiled with C (GNU) compiler.

If z_func() throws, exception is not catched by main function.
Program crashes with error message: terminate called after throwing of
an instance 'of std::exception'

If y.c is compiled with C++ (GNU) compiler, exception is catched by
main function (desired behavior).

The complete source code can be downloaded here:http://freenet-homepage.de/wrungel/exceptions.tgz

The problem is that the y_func() comes from third-party library and
can not be recompiled with C compiler.

How can I catch exceptions in main function caused by z_func()?

y_func() is not yours, is z_func() your code? Can you change it? C
does not have notion of expcetions. So, an exception thrown from C++
code cannot be caught or translated or left to be caught by the
enclosing caller. You will have to not let any C++ exceptions pass
through z_func(). Uncaught exceptions, in a way, form part of the
interface contract (C++ has exception specifications, as well).
Similar to why you cannot have the C++ function z_func() not use
reference arguments (or reference return types), or any other C++
types, not even std::string/std::vector.
 
W

wrungel

y_func() is not yours, is z_func() your code? Can you change it?
z_func() is coded by me.
z_func() is a callback function called by y_func() which is a third-
party libarary function.
Therefore I can not change or recompile y_func().
C does not have notion of expcetions. So, an exception thrown from C++
code cannot be caught or translated or left to be caught by the
enclosing caller.
This is NOT true if you are using GCC.
The option -fexceptions enables exception handling (passing through)
by C-functions.
But I can not use this option for y_func() because I can not recompile
it.
 
K

Kira Yamato

Using extern "C" declarations for y_func() and z_func().

I uploaded same code as zip archive:
http://freenet-homepage.de/wrungel/exceptions.zip

I think this is the problem: you've declared z_func() with extern "C".

The following test program

#include <iostream>

using namespace std;

extern "C"
{
void callc()
{
throw "oh no!";
}
};

int main()
{
callc();
return 0;
}

causes the runtime error message:

terminate called after throwing an instance of 'char const*'
Abort trap

So, I suppose declaring a function extern "C" changes the way it uses
the stack; hence giving you problems when that function throws an
exception.

It seems that there is no way to throw an exception across a stack
frame involving a genuine C function.
 
P

Pete Becker

I think this is the problem: you've declared z_func() with extern "C".

No, that's got nothing to do with it.
The following test program

#include <iostream>

using namespace std;

extern "C"
{
void callc()
{
throw "oh no!";
}
};

int main()
{
callc();
return 0;
}

causes the runtime error message:

terminate called after throwing an instance of 'char const*'
Abort trap

As it should. There's no catch clause. If you wrap the call to callc()
in a try/catch block, this will work just fine.
So, I suppose declaring a function extern "C" changes the way it uses
the stack; hence giving you problems when that function throws an
exception.

No, extern "C" functions can still throw and catch exceptions if
they're compiled as C++.
It seems that there is no way to throw an exception across a stack
frame involving a genuine C function.

That's a different matter. A C function, compiled with a C compiler,
doesn't know anything about exceptions.
 
K

Kira Yamato

As it should. There's no catch clause. If you wrap the call to callc()
in a try/catch block, this will work just fine.

Ah, silly me. :) You're right. Sorry about that.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top