views:

105

answers:

2

I have C++ code that uses some C libraries. The C libraries take C language callbacks. I wrote a callback in my C++ code and now I somehow need to report error from it (but it returns void). I wonder if I can throw an exception from a C callback that is used from C++ code?

This is very difficult for me to understand.

Thanks, Boda Cydo.

+7  A: 

Yes, you should be able to do so. However, keep in mind it's entirely likely that the C library was not written to be exception safe, and as a result you might leave some of that library's structures in some inconsistent state. It depends entirely on the specific library and on the specific callback function. If nothing else, that library would probably have to be written with C++ support in mind from the beginning with respect to that callback.

Billy ONeal
+1 good point, the C library could allocate memory, open a file or a network connection prior to calling the callback function. If you throw an exception there, the library does not clear up afterwards.
Ozan
Thanks for the tips. I made it use a global variable that gets set if error occurred. All subsequent calls to this C callback function then just return and do nothing. After the library is done with all the C calls, and I get back to my C++ code, I check if this global variable was set, and if it was, I report error.
bodacydo
Your first two statements are mutually contradictory. "Yes, you should be able to do so." - OK, good. "However, keep in mind it's entirely likely that the C library was not written to be exception safe," - Oh, so the answer is actually no then. Never throw exceptions across code that is not known to be exception safe.
JeremyP
@JeremyP: Yes, the statements are contradictory if you've never looked at the code for the C library. But if you have, there's no technical reason you shouldn't be able to throw the exception. It just might be a bad idea if the library was not designed to take it. C itself does not have exceptions, but it's entirely possible some C code is written to be exception safe as a result of third party extensions, such as SEH on Windows.
Billy ONeal
@Billy ONeal: I think "could cause memory and other resource leaks" counts as a technical reason.
JeremyP
@JeremyP: But it could not cause memory and other resource leaks as well. That depends on the specific library and specific callback.
Billy ONeal
@Billy ONeal: and you can divine that just by looking at the API can you?
JeremyP
@JeremyP: No. But if you have access to the source code you can. Plenty of APIs follow a pattern of Start -> Do some asynchronous work -> Call callback, in which case all their work would be finished before the callback is run.
Billy ONeal
@Billy ONeal: So it's always going to be a simple affair to check the source code of every library I want to throw an exception through is it? And the library author is never ever going to make code that was exception safe unsafe. Yes, there are some cases where it is safe to throw exceptions through C code, but you can't generalise.
JeremyP
@JeremyP: My point is that's entirely the domain of the library. There's nothing specific about the C and C++ languages which prevent this. I don't see how I have generalized beyond that point.
Billy ONeal
@JeremyP: I additionally note that the exception safe problem is something that has to be maintained by any code dealing with exceptions, not just C/C++ callbacks. Of course it has to be safe to throw an exception in the first place before you're going to be able to throw one from a callback. Callbacks do not change that rule.
Billy ONeal
A: 

Yes, you could throw an exception from your C++ function. However, it can only be caught by C++ code so it won't be handled in the legacy library.

Duracell
Did you mean to say "from you C function"?
egrunin
No. If you throw an exception, then the function is not C, is it?
Duracell
Good point. Is it C callback then or C++ callback if I throw from it?
bodacydo
If your callback belongs to a C++ compiled unit, then you can say it's C++.
jweyrich