What happens if exception gets thrown "through" c code? [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Will C++ exceptions safely propagate through C code?
If you have c code, for example the png lib, with your own io handlers which are written in c++ and an exception gets thrown due to some io error. is it ok to let it go through the c code and catch it outside of the c code? i know that care has to be taken with memory leaks but typically all structures get pre-allocated.

It is entirely up to the compiler if this will work or not. None of the language standards can obviously say anything about what the other language should do.
In the best case, the exception will pass the C code and get back to the next C++ level while possibly leaking any dynamically allocated C structures. In the less good case, it will crash and burn!
One possibilty is of course to compile the C code as C++, while also checking that it is exception neutral.

The answer to your question is implementation-defined.
For GCC, as #Kerrek says, compiling the C code with -fexceptions will ensure the run-time remains consistent when an exception is thrown through C code. (Note that modern exception mechanisms are not just implemented via setjmp/longjmp; they actually unwind the stack frame by frame in order to handle destructors and try/catch blocks properly.)
However, the C code itself may not be expecting to have exceptions thrown through it. Lots of C code is written like this:
acquire a resource
do some stuff
release resource
Here "acquire a resource" could mean malloc, or pthread_mutex_lock, or fopen. If your C++ code is part of the "do some stuff", and it throws an exception, well... Whoops.
Resource leaks are not the only problem; so is correctness is general. Imagine:
subtract $100 from savings account
add $100 to checking account
Now imagine an exception gets thrown after the first step finishes but before the second one does.
In short, although your implementation may provide a way to let you throw exceptions through C code, it is a bad idea unless you also wrote that C code knowing exactly where an exception might be thrown.

It's okay for your C++ code if it's:
Compiled with exceptions enabled.
Exception safe.
It's okay for your C or C++ code if:
No resources need to be collected explicitly between the throwing of the exception, and its being caught.
Code compiled with C++ exception support adds special hooks to clean up when exceptions are thrown and not caught in that scope. C++ objects allocated on the stack will have their destructors invoked.
The only resource reclaimed in C (or C++ without exception support) when an exception is thrown is the space allocated in each stack frame.
This section of the GCC manual is quite helpful:
-fexceptions
Enable exception handling. Generates extra code needed to
propagate exceptions. For some targets, this implies GCC will
generate 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 will enable it
by default for languages like C++ which normally require exception
handling, and disable 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.

Exceptions aren't usually really thrown "through" code; as the action implies, they are thrown "over" code.
As a forinstance; at least old-school Objective-C exceptions are usually implemented with setjmp and longjmp; essentially storing the addresses of code for later use.
It makes sense for C++ exceptions to be implemented with similar mechanisms; and as such; the type of code the exception is thrown "through", or more accurately, "over" matters little, if at all. One could even imagine a setting where an Objective-C exception is thrown over a C++ catch, or vice versa.
Edit: As Bo Persson mentiones; this is not to say that a C++ exception interrupting C code wouldn't cause havoc and leaks; but exceptions being thrown is usually a Bad Thing™ all round; so it's not likely to matter much.
PS: Kudos on actually asking a question where using both C and C++ tags is relevant. ;)

C doesn't know anything about exceptions so it's not possible to say what would happen.
To write conforming code you'd need to catch exceptions prior to returning into the C library, translate to error codes, and then translate the C-library error back into an exception on the other end.

Related

which system software is responsible for Run time check

I thought this would sound a general simple question but I got up this when reading C++ exception specification. that said in one of the book, C++11 now have a keyword 'noexcept' that means no exception will be thrown from a function when it is declared with the function header and that said the reason for this keyword came into existence is C++ exception specifications are checked at run time rather than at compile time, so they offer no programmer guarantees that all exceptions have been handled. and hence they conclude two case a function would throw exception or if we are clear if it will never throw, then use noexcept for optimization(hopefully)
void foo() noexcept();
Here is the main question. Which system software perform those run time checking(I hope not compiler/linker/loader) and also which system software is responsible for allocating memory at run time(dynamic memory allocation) when this are all not taken care by compiler and others?
There is no active "system software" checking for exceptions, as you phrase it; rather, throwing an exception is an action taken by the program itself. The program passes the exception back up the stack until the exception matches an exception handler.
If no exception handler matches, then the exception is caught by the bootstrap code (main is not the actual entry point for a typical program, but is where the runtime hands control to the programmer) and the program terminates.
AFAIK this is done by the C++ runtime (libstdc++ for example). In case of exceptions, there are some guards added around the functions by the compiler (this is necessary anyway to call destructors in case exception is thrown), and in the case of noexcept, if the function throws (or if it throws other exception than advertised by the throw() specification), terminate() is called by the C++ runtime and the application is shut down.
Memory heap allocations are also (by default) done by the C++ runtime libraries.
Typically the responsible software isn't one clearly identifiable piece of code, but small fragments of code sprinkled through the executable. The compiler translates your code into binary instructions, and noexcept is no exception ;).
Indeed, you would not say that the "standard library" handles this. Exceptions and exception specifications are rather a core language feature, more fundamental than the standard library.
You could similarly ask, what piece of software ensures that when I call a function in C++, that the caller actually receives the values that I pass in? What piece of software manipulates the stack frame pointers while my program is running?
From the point of view of the standard I would say "the implementation" is responsible for these details. In some languages, like Java for instance, there is a "Java Runtime Environment" which is very clearly responsible for these things, and you could try to study exactly how it does them. In C++ there is no universal runtime environment -- like others have said, the compiler is responsible to generate code that ensures that these things happen, and that code ends up sprinkled throughout your resulting executable. How exactly the compiler achieves its task is implementation-specific, you can't give a general answer beyond what the standard says, and generally it specifies the expected behavior, not the details under the hood.
When you ask
also which system software is responsible for allocating memory at run time(dynamic memory allocation
this is again an implementation detail, it will differ from compiler to compiler.

How to turn off exception handling?

In the book More Effective C++ (Number 15), I read that code becomes significantly slower if exceptions are enabled, even if they are not used. In my opinion, exceptions are of limited use, and I try to avoid them, but this is another topic.
I do not entirely understand his statement:
What does enabling/disabling exceptions mean? It it the difference between having zero or more than zero try/catch blocks? Is it a compiler flag? What happens if I use a DLL in which exceptions can occur?
Suppose no exception is ever thrown:
Does the code become slower as a whole or are only the parts where the program enters/exits try/catch blocks become slower? According to the author, both is true.
How can I compile without exceptions? Can I do this even if I have try/catch blocks? Can I do this if DLLs I use might throw exceptions?
What does enabling/disabling exceptions mean?
Passing a flag to the compiler which disables standard conformance in relation to exceptions and makes it not generate any exception support.
What happens if I use a DLL in which exceptions can occur?
If some library handles exception internally, nothing. If it lets it escape to the caller (I never saw any library which does that, because of ABI issues, but whatever), your program crashes (in best case) as it cannot handle it. If there is a wrapper for DLL which your code include and which converts error codes to exceptions (common occurence), then it is the same as if you used exceptions in your code.
Does the code become slower as a whole or are only the parts where the program enters/exits try/catch blocks become slower? According to the author, both is true.
Notice that the book you are citing is old. Compilers are evolving. Modern compilers use zero-cost exceptions which do not incure perfomance cost if exception is not thrown. Exception handling does make executable larger as it should generate all data and code needed to process exceptions, but it should not make it slower on non-exceptional path.
How can I compile without exceptions? Can I do this even if I have try/catch blocks?
You do that in compiler-specific way. Consult your compiler documentation. Usually doing so makes compiler reject code containing any exception-related facilities, e.g. point out try as unrecognised identifier.

Disabling C++ exceptions, how can I make any std:: throw() immediately terminate?

This C++ program is a CGI script, I have no desire to deal with exceptions. I'd rather get a marginal performance boost and let the OS (Linux) handle cleanup after the process dies.
I am using the Standard C++ Library, and want any function to die like in Perl: Whenever it throws an exception. Without unwinding, or running any further code in my process.
How does -fno-exceptions work? If I have no catch at all in my code, and basically pretend like exceptions do no exist. but I do use std:: c++ library which can throw()?
Option #1: Simply never catch exceptions.
Exceptions don't have much overhead when they're not thrown or caught; if you're throwing and not prepared to catch, well, you're doing to die anyway, so the performance impact at that point is trivial. Note also that stack unwinding will not be performed if an exception is not handled; the program will simply terminate without performing stack unwinding.
It's important to note that, in G++, exceptions have almost no overhead when not actually thrown. G++ generates extra information sufficient to trace back the execution of the program through the stack, and some extra code to invoke destructors, etc - however none of this extra code or data is ever used until an exception is actually thrown. So you should not see a performance difference between code with exceptions enabled but not used and code with exceptions disabled (through whatever mechanism).
Option #2: Pass -fno-exceptions.
This flag instructs G++ to do two things:
All exception handling in STL libraries are removed; throws are replaced with abort() calls
Stack unwind data and code is removed. This saves some code space, and may make register allocation marginally easier for the compiler (but I doubt it'll have much performance impact). Notably, however, if an exception is thrown, and the library tries to unwind through -fno-exceptions code, it will abort at that point, as there is no unwind data.
This will, effectively, turn all exceptions into abort()s, as you would like. Note, however, that you will not be allowed to throw - any actual throws or catchs in your code will result in a compile-time error.
Option #3: (Nonportable and not recommended!) Hook __cxa_allocate_exception.
C++ exceptions are implemented using (among others) the __cxa_allocate_exception and __cxa_throw internal library functions. You can implement a LD_PRELOAD library that hooks these functions to abort():
void __cxa_allocate_exception() { abort(); }
void __cxa_throw() { abort(); }
WARNING: This is a horrible hack. It should work on x86 and x86-64, but I strongly recommend against this. Notably, it won't actually improve performance or save code space, as -fno-exceptions might. However, it will allow the throw syntax, while turning throws into abort()s.
-fno-exceptions turns all standard library throw's into a call to std::abort(). That handles the part you can't modify directly, the rest is to not use them at all in your code.
Of course, I really doubt your justification in doing this. You only "lose" performance when you actually throw, and you're throwing out a significant and helpful bit of the language.
In case anyone stumbles upon this question, I'd like to correct what #GManNickG and (https://stackoverflow.com/a/7249460/157344) and #bdonlan (https://stackoverflow.com/a/7249442/157344) said in their answers. Unfortunately the part about "-fno-exception" removing all exception handling code and turning all throws into aborts is wrong. Well - partially wrong. This is true when you compile the library in question (libstdc++v3) with this flag, but not true if you use this library (as an .a or .so or .dll or whatever) in your own code compiled with this flag. In the latter case the exception handling code in YOUR code is forbidden, but all the calls to exception handling inside the library remain (because the library was compiled WITHOUT this flag, with exceptions enabled), so if you use new then your executable WILL have exception handling code - the only difference is that you cannot anything about these exceptions with a catch() (which is forbidden in your code), so all throws effectively end up as abort(), but only because no one catches them.
Quote:
This C++ program is a CGI script, I have no desire to deal with exceptions.
Then don't. Simple. The exception will get to the top of the stack very quickly.
But I would urge you to do so. To do so means that you are thinking of the things that can go wrong.
Just don't catch them anywhere in your code. In that case, a termination handler will be called and your program will "crash".

What are the consequences of mixing exception handling models in Visual Studio 2010?

I have third-party static library built with Enable C++ Exceptions set to No (/EH flag not specified). What are the consequences to calling into it from code built with C++ exceptions enabled (/EHa)? If a Structured Exception is thrown from within the library, will the function provided to _set_se_translator by the main application be reliably called? (My experiments show that it will, but just wondering if this is defined behavior).
Are there any other considerations when mixing /EH exception handing models?
Calling into code which does not have exceptions enabled shouldn't produce any problems -- this is no different than calling an external C function or something of that nature.
Calling from code which does not have exceptions enabled (into exception enabled code) will probably not contain the correct stack unwinding semantics in the exception disabled code, which means you'll be breaking invariants of that code, unless it was specifically designed to work with exceptions. (For example, some libraries (e.g. ANTLR) allocate all memory in a block and have the user code free everything at once, allowing exceptions to be used without leaking even though they themselves do not use exceptions).
Raymond Chen has quite an article about the innards of how C++'s exception handling works on MSVC++. Long story short, it's built on top of Windows' SEH. Therefore it should behave similarly to what happens if you throw a SEH exception in e.g. C code. (However, I've not verified this myself)
According to the MSDN then one is allowed to mix /EHa and /EHsc:
The two exception handling models, synchronous and asynchronous, are fully compatible and can be mixed in the same application.
But there seems to an exception to this rule, and that is when passing exceptions from unmanaged (/EHsc) to managed (/clr). The managed codes catches all exceptions using structured exception handling (SEH), and this causes unmanaged destructors not to be called when unwinding the stack. There are different workarounds:
Change the unmanaged code to use /EHa instead of /EHsc. This has the downside that catch(...) within unmanaged code suddenly will catch access violations and other crazy stuff.
Create try-catch block within the unmanaged code, and ensure that no exceptions are passed between the unmanaged world and the managed world.
2.1. Possible middle road is to ensure that no destructors are expected to be called when passing exception from unmanaged to managed world. Within the unmanaged code make a try-catch wrapper, and then in the catch-block rethrow the exception into the managed world.

ANTLR3 C Target with C++ Exceptions

I have some experience with ANTLR 2's C++ target, but have been hesitant to spend much time on ANTLR 3 because of my fears about exception safety.
Sadly, ANTLR 3 only has a C target which produces C which is "C++ compatible." This does not seem to include C++ exception safety, based on the following:
You can probably use [exceptions] carefully,
but as you point out, you have to be
careful with memory. The runtime
tracks all its normal memory
allocations so as long as you close
the 'classes' correctly you should
generally be OK. However, you should
make sure that throwing exceptions
does not bypass the normal rule clean
up, such as resetting error and
backtracking flags and so on.
(ANTLR-interest, circa 2009)
Does anyone have any experience using the ANTLR C target with (advanced) C++? Is it possible to safely throw exceptions? What extra code (if any) do I have to write to make it safe?
I don't have any ANTLR experience (sadly...), but there is NO way to make C code work with exceptions around. I refer you to More Effective C++, item 9 : "Use destructors to prevent resource leaks"
The idea is that if an exception is thrown during cleanup, you have no information on what is already delete()ed an what is not, and your software will leak memory. If you use auto_ptr/scroped_ptr, ou don't have to worry about this, since the compiler will deal with it itself.
But this idiom is C++-only, C was not designed with exceptions in mind.