14

I have three free functions: F0, F1 and F2. F0 calls F1, which in turn calls F2.

F0 and F2 are C++ functions, where as F1 is a C function. F2 is exposed to F1 via: extern "C"

The code for each of the free functions is as follows:

~~~~ F0.cpp ~~~~

void f0()
{
   try
   {
      f1();
   }
   catch (...)
   {}
}

~~~~ F0.cpp ~~~~


~~~~ F1.c ~~~~

void f1()
{
   f2();
}

~~~~ F1.c ~~~~


~~~~ F2.cpp ~~~~

void f2()
{
  throw 1
}

~~~~ F2.cpp ~~~~

Question:

Does the exception thrown in f2 progress through f1 and caught correctly in f0?

Or is std::unexpected invoked due to the exception not being handled, or is the whole thing supposed to be undefined behavior? - if so where in the standard does it talk about exception handling in this particular context.


Please note this is not about handling exceptions in C, but rather what happens in the situation where the exception can flow through the C layer (if at all) and be caught in the calling C++ layer - and any resulting side effects etc.

Stargateur
  • 24,473
  • 8
  • 65
  • 91
J Mkdjion
  • 352
  • 1
  • 11
  • 1
    Possible duplicate of [Can a C program handle C++ exceptions?](https://stackoverflow.com/questions/4448677/can-a-c-program-handle-c-exceptions) – Eugene Sh. Apr 27 '18 at 20:13
  • 1
    @EugeneSh. this is not about handling exceptions in C, but rather what happens in the situation where the exception can flow through the C layer and be caught in the calling C++ layer - and any resulting side effects. – J Mkdjion Apr 27 '18 at 20:21
  • It can't. "Flow" - means getting caught and re-thrown. – Eugene Sh. Apr 27 '18 at 20:23
  • @EugeneSh. ok, if thats the case then is std::unexpected invoked? also is the C portion of the stack properly unwound? – J Mkdjion Apr 27 '18 at 20:24
  • 1
    Actually I found [this SQL duplicate candidate](https://stackoverflow.com/questions/2101390/will-c-exceptions-safely-propagate-through-c-code). If it is your own C code and you know it is harmless I recon you are OK, but if your C code has allocated resources it expects to free on return, that won't happen. It was always intended that c++ functions that are exception neutral and have no auto var destruction should be as efficient as the same C code, but that doesn't mean it is identical. – Gem Taylor Apr 27 '18 at 20:27
  • I think your question is implemented behavior. You should specified your compiler, your system, etc... But I don't understand why and how a c code could call a c++ function. – Stargateur Apr 27 '18 at 20:28
  • @GemTaylor that is pretty much the scenario I'm facing and was hoping there'd be an explanation that applies generally and hopefully is not implementation defined, though most of the answers on that Q, don't seem to reach consensus. – J Mkdjion Apr 27 '18 at 20:40
  • Are you interested in a language lawyer answer, or rather just what happens? If the latter, why not just compile it and see what happens? – C.J. Apr 27 '18 at 20:40
  • Sorry, but what is `throw 1` ? – Paul Jan 17 '20 at 15:46

2 Answers2

13

This is platform-specific and compiler-specific question.

For example, on Linux/GCC, you have to compile C code with -fexceptions option, then unwind tables would be build and exception will go throw C code.

From https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions

-fexceptions

Enable exception handling. Generates extra code needed to propagate exceptions. For some targets, this implies GCC generates frame unwind information for all functions, which can produce significant data size overhead, although it does not affect execution. If you do not specify this option, GCC enables it by default for languages like C++ that normally require exception handling, and disables it for languages like C that do not normally require it. However, you may need to enable this option when compiling C code that needs to interoperate properly with exception handlers written in C++. You may also wish to disable this option if you are compiling older C++ programs that don’t use exception handling.

I'm less familiar with Visual C++/Windows development, but I believe exceptions handling will use common mechanisms if you compile your C++ and C code with /EHa option (allow mix of structured and C++ exceptions)

bolov
  • 72,283
  • 15
  • 145
  • 224
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
0

I just stumbled on this problem when I realised my MSVC project is using a C library that is passed a C++ error handler that throws exceptions. The release build would crash before reaching the catch clause with an unexpected "write access violation" instead.

In Visual Studio go to your project's properties page > Configuration Properties > C/C++ > Code Generation > Enable C++ Exceptions. Set the property to "Yes with Extern C functions (/EHs)" to let the compiler know that it should also expect extern "C" functions to throw.

Check Microsoft documentation here.

Jacek C.
  • 180
  • 1
  • 6