9

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.

bodacydo
  • 75,521
  • 93
  • 229
  • 319

2 Answers2

9

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
  • 104,103
  • 58
  • 317
  • 552
  • 1
    +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 Jul 05 '10 at 03:08
  • 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 Jul 05 '10 at 03:15
  • 2
    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 Jul 05 '10 at 10:20
  • @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 Jul 05 '10 at 12:20
  • @Billy ONeal: I think "could cause memory and other resource leaks" counts as a technical reason. – JeremyP Jul 05 '10 at 15:26
  • @JeremyP: But it could not cause memory and other resource leaks as well. That depends on the specific library and specific callback. – Billy ONeal Jul 06 '10 at 00:49
  • @Billy ONeal: and you can divine that just by looking at the API can you? – JeremyP Jul 06 '10 at 07:28
  • @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 Jul 06 '10 at 11:50
  • @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 Jul 06 '10 at 12:29
  • @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 Jul 06 '10 at 20:13
  • @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 Jul 06 '10 at 20:15
1

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.

Anthony
  • 12,177
  • 9
  • 69
  • 105