Are Exceptions in C++ really slow - c++

I was watching Systematic Error Handling in C++—Andrei Alexandrescu he claims that Exceptions in C++ are very very slow.
Is this still true for C++98?

The main model used today for exceptions (Itanium ABI, VC++ 64 bits) is the Zero-Cost model exceptions.
The idea is that instead of losing time by setting up a guard and explicitly checking for the presence of exceptions everywhere, the compiler generates a side table that maps any point that may throw an exception (Program Counter) to the a list of handlers. When an exception is thrown, this list is consulted to pick the right handler (if any) and stack is unwound.
Compared to the typical if (error) strategy:
the Zero-Cost model, as the name implies, is free when no exceptions occur
it costs around 10x/20x an if when an exception does occur
The cost, however, is not trivial to measure:
The side-table is generally cold, and thus fetching it from memory takes a long time
Determining the right handler involves RTTI: many RTTI descriptors to fetch, scattered around memory, and complex operations to run (basically a dynamic_cast test for each handler)
So, mostly cache misses, and thus not trivial compared to pure CPU code.
Note: for more details, read the TR18015 report, chapter 5.4 Exception Handling (pdf)
So, yes, exceptions are slow on the exceptional path, but they are otherwise quicker than explicit checks (if strategy) in general.
Note: Andrei Alexandrescu seems to question this "quicker". I personally have seen things swing both ways, some programs being faster with exceptions and others being faster with branches, so there indeed seems to be a loss of optimizability in certain conditions.
Does it matter ?
I would claim it does not. A program should be written with readability in mind, not performance (at least, not as a first criterion). Exceptions are to be used when one expects that the caller cannot or will not wish to handle the failure on the spot, and pass it up the stack. Bonus: in C++11 exceptions can be marshalled between threads using the Standard Library.
This is subtle though, I claim that map::find should not throw but I am fine with map::find returning a checked_ptr which throws if an attempt to dereference it fails because it's null: in the latter case, as in the case of the class that Alexandrescu introduced, the caller chooses between explicit check and relying on exceptions. Empowering the caller without giving him more responsibility is usually a sign of good design.

When the question was posted I was on my way to the doctor, with a taxi waiting, so I only had time then for a short comment. But having now commented and upvoted and downvoted I’d better add my own answer. Even if Matthieu’s answer already is pretty good.
Are exceptions especially slow in C++, compared to other languages?
Re the claim
“I was watching Systematic Error Handling in C++—Andrei Alexandrescu he claims that Exceptions in C++ are very very slow.”
If that’s literally what Andrei claims, then for once he’s very misleading, if not downright wrong. For a raised/thrown exceptions is always slow compared to other basic operations in the language, regardless of the programming language. Not just in C++ or more so in C++ than in other languages, as the purported claim indicates.
In general, mostly regardless of language, the two basic language features that are orders of magnitude slower than the rest, because they translate to calls of routines that handle complex data structures, are
exception throwing, and
dynamic memory allocation.
Happily in C++ one can often avoid both in time-critical code.
Unfortunately There Ain’t No Such Thing As A Free Lunch, even if the default efficiency of C++ comes pretty close. :-) For the efficiency gained by avoiding exception throwing and dynamic memory allocation is generally achieved by coding at a lower level of abstraction, using C++ as just a “better C”. And lower abstraction means greater “complexity”.
Greater complexity means more time spent on maintenance and little or no benefit from code reuse, which are real monetary costs, even if difficult to estimate or measure. I.e., with C++ one can, if so desired, trade some programmer efficiency for execution efficiency. Whether to do so is largely an engineering and gut-feeling decision, because in practice only the gain, not the cost, can be easily estimated and measured.
Are there any objective measures of C++ exception throwing performance?
Yes, the international C++ standardization committee has published a Technical Report on C++ performance, TR18015.
What does it mean that exceptions are “slow”?
Mainly it means that a throw can take a Very Long Time™ compared to e.g. an int assignment, due to the search for handler.
As TR18015 discusses in its section 5.4 “Exceptions” there are two principal exception handling implementation strategies,
the approach where each try-block dynamically sets up exception catching, so that a search up the dynamic chain of handlers is performed when an exception is thrown, and
the approach where the compiler generates static look-up tables that are used to determine the handler for a thrown exception.
The first very flexible and general approach is almost forced in 32-bit Windows, while in 64-bit land and in *nix-land the second far more efficient approach is commonly used.
Also as that report discusses, for each approach there are three main areas where exception handling impacts on efficiency:
try-blocks,
regular functions (optimization opportunities), and
throw-expressions.
Mainly, with the dynamic handler approach (32-bit Windows) exception handling has an impact on try blocks, mostly regardless of language (because this is forced by Windows' Structured Exception Handling scheme), while the static table approach has roughly zero cost for try-blocks. Discussing this would take a lot more space and research than is practical for an SO answer. So, see the report for details.
Unfortunately the report, from 2006, is already a little bit dated as of late 2012, and as far as I know there’s not anything comparable that’s newer.
Another important perspective is that the impact of use of exceptions on performance is very different from the isolated efficiency of the supporting language features, because, as the report notes,
“When considering exception handling, it must be contrasted to alternative ways of
dealing with errors.”
For example:
Maintenance costs due to different programming styles (correctness)
Redundant call site if failure checking versus centralized try
Caching issues (e.g. shorter code may fit in cache)
The report has a different list of aspects to consider, but anyway the only practical way to obtain hard facts about the execution efficiency is probably to implement the same program using exception and not using exceptions, within a decided cap on development time, and with developers familiar with each way, and then MEASURE.
What is a good way to avoid the overhead of exceptions?
Correctness almost always trumps efficiency.
Without exceptions, the following can easily happen:
Some code P is meant to obtain a resource or compute some information.
The calling code C should have checked for success/failure, but doesn't.
A non-existent resource or invalid information is used in code following C, causing general mayhem.
The main problem is point (2), where with the usual return code scheme the calling code C is not forced to check.
There are two main approaches that do force such checking:
Where P directly throws an exception when it fails.
Where P returns an object that C has to inspect before using its main value (otherwise an exception or termination).
The second approach was, AFAIK, first described by Barton and Nackman in their book *Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples, where they introduced a class called Fallow for a “possible” function result. A similar class called optional is now offered by the Boost library. And you can easily implement an Optional class yourself, using a std::vector as value carrier for the case of non-POD result.
With the first approach the calling code C has no choice but to use exception handling techniques. With the second approach, however, the calling code C can itself decide whether to do if based checking, or general exception handling. Thus, the second approach supports making the programmer versus execution time efficiency trade-off.
What is the impact of the various C++ standards, on exception performance?
“I want to know is this still true for C++98”
C++98 was the first C++ standard. For exceptions it introduced a standard hierarchy of exception classes (unfortunately rather imperfect). The main impact on performance was the possibility of exception specifications (removed in C++11), which however were never fully implemented by the main Windows C++ compiler Visual C++: Visual C++ accepts the C++98 exception specification syntax, but just ignores exception specifications.
C++03 was just a technical corrigendum of C++98. The only really new in C++03 was value initialization. Which has nothing to do with exceptions.
With the C++11 standard general exception specifications were removed, and replaced with the noexcept keyword.
The C++11 standard also added support for storing and rethrowing exceptions, which is great for propagating C++ exceptions across C language callbacks. This support effectively constrains how the current exception can be stored. However, as far as I know that does not impact on performance, except to the degree that in newer code exception handling may more easily be used on both sides of a C language callback.

You can never claim about performance unless you convert the code to the assembly or benchmark it.
Here is what you see: (quick-bench)
The error code is not sensitive to the percentage of occurrence. Exceptions have a little bit overhead as long as they are never thrown. Once you throw them, the misery starts. In this example, it is thrown for 0%, 1%, 10%, 50% and 90% of the cases. When the exceptions are thrown 90% of the time, the code is 8 times slower than the case where the exceptions are thrown 10% of the time. As you see, the exceptions are really slow. Do not use them if they are thrown frequently. If your application has no real-time requirement, feel free to throw them if they occur very rarely.
You see many contradictory opinions about them. But finally,
are exceptions are slow? I don't judge. Just watch the benchmark.

It depends on the compiler.
GCC, for example, was known for having very poor performance when handling exceptions, but this got considerably better in the past few years.
But note that handling exceptions should - as the name says - be the exception rather than the rule in your software design. When you have an application which throws so many exceptions per second that it impacts performance and this is still considered normal operation, then you should rather think about doing things differently.
Exceptions are a great way to make code more readable by getting all that clunky error handling code out of the way, but as soon as they become part of the normal program flow, they become really hard to follow. Remember that a throw is pretty much a goto catch in disguise.

Yes, but that doesn't matter.
Why?
Read this:
https://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx
Basically that says that using exceptions like Alexandrescu described (50x slowdown because they use catch as else) is just wrong.
That being said for ppl who like to do it like that
I wish C++22 :) would add something like:
(note this would have to be core language since it is basically compiler generating code from existing one)
result = attempt<lexical_cast<int>>("12345"); //lexical_cast is boost function, 'attempt'
//... is the language construct that pretty much generates function from lexical_cast, generated function is the same as the original one except that fact that throws are replaced by return(and exception type that was in place of the return is placed in a result, but NO exception is thrown)...
//... By default std::exception is replaced, ofc precise configuration is possible
if (result)
{
int x = result.get(); // or result.result;
}
else
{
// even possible to see what is the exception that would have happened in original function
switch (result.exception_type())
//...
}
P.S. also note that even if the exceptions are that slow... it is not a problem if you dont spend a lot of time in that part of the code during execution... For example if float division is slow and you make it 4x faster that doesnt matter if you spend 0.3% of your time doing FP division...

Like in silico said its implementation dependent, but in general exceptions are considered slow for any implementation and shouldn't be used in performance intensive code.
EDIT: I'm not saying don't use them at all but for performance intensive code it is best to avoid them.

Related

If you're in the "we don't use exceptions" camp, then how do you use the standard library?

Note: I'm not playing the devil's advocate or anything like that here - I'm just genuinely curious since I'm not in this camp myself.
Most types in the standard library have either mutating functions that can throw exceptions (for instance if memory allocation fails) or non-mutating functions that can throw exceptions (for instance out of bounds indexed accessors). In addition to that, many free functions can throw exceptions (for instance operator new and dynamic_cast<T&>).
How do you practically deal with this in the context of "we don't use exceptions"?
Are you trying to never call a function that can throw? (I can't see how that'd scale, so I'm very interested to hear how you accomplish this if this is the case)
Are you ok with the standard library throwing and you treat "we don't use exceptions" as "we never throw exceptions from our code and we never catch exceptions from other's code"?
Are you disabling exception handling altogether via compiler switches? If so, how do the exception-throwing parts of the standard library work?
EDIT Your constructors, can they fail, or do you by convention use a 2-step construction with a dedicated init function that can return an error code upon failure (which the constructor can't), or do you do something else?
EDIT Minor clarification 1 week after the inception of the question... Much of the content in comments and questions below focus on the why aspects of exceptions vs "something else". My interest is not in that, but when you choose to do "something else", how do you deal with the standard library parts that do throw exceptions?
I will answer for myself and my corner of the world. I write c++14 (will be 17 once compilers have better support) latency critical financial apps that process gargantuan amounts of money and can't ever go down. The ruleset is:
no exceptions
no rtti
no runtime dispatch
(almost) no inheritance
Memory is pooled and pre-allocated, so there are no malloc calls after initialization. Data structures are either immortal or trivially copiable, so destructors are nearly absent (there are some exceptions, such as scope guards). Basically, we are doing C + type safety + templates + lambdas. Of course, exceptions are disabled via the compiler switch. As for the STL, the good parts of it (i.e.: algorithm, numeric, type_traits, iterator, atomic, ...) are all useable. The exception-throwing parts coincide with the runtime-memory-allocating parts and the semi-OO parts nicely so we get to get rid of all the cruft in one go: streams, containers except std::array, std::string.
Why do this?
Because like OO, exception offers illusory cleanliness by hiding or moving the problem elsewhere, and makes the rest of the program harder to diagnose. When you compile without "-fno-exceptions", all your clean and nicely behaved functions have to endure the suspicion of being failable. It is much easier to have extensive sanity checking around the perimeter of your codebase, than to make every operation failable.
Because exceptions are basically long range GOTOs that have an unspecified destination. You won't use longjmp(), but exceptions are arguably much worse.
Because error codes are superior. You can use [[nodiscard]] to force calling code to check.
Because exception hierarchies are unnecessary. Most of the time it makes little sense to distinguish what errored, and when it does, it's likely because different errors require different clean-up and it would have been much better to signal explicitly.
Because we have complex invariants to maintain. This means that there are code, however deep down in the bowels, that need to have transnational guarantees. There are two ways of doing this: either you make your imperative procedures as pure as possible (i.e.: make sure you never fail), or you have immutable data structures (i.e.: make failure recovery possible). If you have immutable data structures, then of course you can have exceptions, but you won't be using them because when you will be using sum types. Functional data structures are slow though, so the other alternative is to have pure functions and do it in an exception-free language such as C, no-except C++, or Rust. No matter how pretty D looks, as long as it isn't cleansed of GC and exceptions, it's an non-option.
Do you ever test your exceptions like you would an explicit code path? What about exceptions that "can never happen"? Of course you don't, and when you actually hit those exceptions you are screwed.
I have seen some "beautiful" exception-neutral code in C++. That is, it performs optimally with no edge cases regardless of whether the code it calls uses exceptions or not. They are really hard to write and I suspect, tricky to modify if you want to maintain all your exception guarantees. However, I have not seen any "beautiful" code that either throws or catches exceptions. All code that I have seen that interacts with exceptions directly have been universally ugly. The amount of effort that went into writing exception-neutral code completely dwarfs the amount of effort that was saved from the crappy code that either throws or catches exceptions. "Beautiful" is in quotes because it is not actual beauty: it is usually fossilized because editing it requires the extra burden of maintaining exception-neutrality. If you don't have unit tests that deliberately and comprehensively misuse exceptions to trigger those edge cases, even "beautiful" exception-neutral code decays into manure.
In our case, we disable the exceptions via the compiler (e.g -fno-exceptions for gcc).
In the case of gcc, they use a macro called _GLIBCXX_THROW_OR_ABORT which is defined as
#ifndef _GLIBCXX_THROW_OR_ABORT
# if __cpp_exceptions
# define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC))
# else
# define _GLIBCXX_THROW_OR_ABORT(_EXC) (__builtin_abort())
# endif
#endif
(you can find it in libstdc++-v3/include/bits/c++config on latest gcc versions).
Then you juste have to deal with the fact that exceptions thrown just abort. You can still catch the signal and print the stack (there is a good answer on SO that explains this), but you have better avoid this kind of things to happen (at least in releases).
If you want some example, instead of having something like
try {
Foo foo = mymap.at("foo");
// ...
} catch (std::exception& e) {}
you can do
auto it = mymap.find("foo");
if (it != mymap.end()) {
Foo foo = it->second;
// ...
}
I also want to point out, that when asking about not using exceptions, there's a more general question about standard library: Are you using standard library when you're in one of the "we don't use exceptions" camps?
Standard library is heavy. In some "we don't use exceptions" camps, like many GameDev companies for example, better suited alternatives for STL are used - mostly based on EASTL or TTL. These libraries don't use exceptions anyway and that's because eighth generation consoles didn't handle them too well (or even at all). For a cutting edge AAA production code, exceptions are too heavy anyway, so it's a win - win scenario in such cases.
In other words, for many programmers, turning exceptions off goes in pair with not using STL at all.
Note I use exceptions... but I have been forced not to.
Are you trying to never call a function that can throw? (I can't see how that'd scale, so I'm very interested to hear how you accomplish this if this is the case)
This would probably be infeasible, at least on a large scale. Many functions can land up throwing, avoid them entirely cripples your code base.
Are you ok with the standard library throwing and you treat "we don't use exceptions" as "we never throw exceptions from our code and we never catch exceptions from other's code"?
You pretty much have to be ok with that... If the library code is going to throw an exception and your code is not going to handle it, termination is the default behaviour.
Are you disabling exception handling altogether via compiler switches? If so, how does the exception-throwing parts of the standard library work?
This is possible (back in the day it was sometime popular for some project types); compilers do/may support this, but you will need to consult their documentation for what the result(s) would and could be (and what language features are supported under those conditions).
In general, when an exception would be thrown, the program would need to abort or otherwise exit. Some coding standards still require this, the JSF coding standard comes to mind (IIRC).
General strategy for those who "don't use exceptions"
Most functions have a set of preconditions that can be checked for before the call is made. Check for those. If they are not met, then don't make the call; fall back to whatever the error handling is in that code. For those functions that you can't check to ensure the preconditions are met... not much, the program will likely abort.
You could look to avoid libraries that throw exceptions - you asked this in the context of the standard library, so this doesn't quite fit the bill, but it remains an option.
Other possible strategies; I know this sounds trite, but pick a language that doesn't use them. C could do nicely...
...crux of my question (your interaction with the standard library, if any), I'm quite interested in hearing about your constructors. Can they fail, or do you by convention use a 2-step construction with a dedicated init function that can return an error code upon failure (which the constructor can't)? Or what's your strategy there?
If constructors are used, there are generally two approaches that are used to indicate the failure;
Set an internal error code or enum to indicate the failure and what the failure is. This can be interrogated after the object's construction and appropriate action taken.
Don't use a constructor (or at least only construct what cannot fail in the constructor - if anything) and then use an init() method of some sort to do (or complete) the construction. The member method can then return an error if there is some failure.
The use of the init() technique is generally favored as it can be chained and scales better than the internal "error" code.
Again, these are techniques that come from environments where exceptions do not exist (such as C). Using a language such as C++ without exceptions limits its usability and the usefulness of the breadth of the standard library.
Not trying to fully answer the questions you have asked, I will just give google as an example for code base which does not utilize exceptions as a mechanism to deal with errors.
In Google C++ code base, every functions which may fail return a status object which have methods like ok to specify the result of the callee.
They have configurated GCC to fail the compilation if the developer ignored the return status object.
Also, from the little open source code they provide (such as LevelDB library), it seems they are not using STL that much anyway, so exception handling become rare. as Titus Winters says in his lectures in CPPCon, they "Respect the standard, but don't idolize it".
I think this is an attitude question. You need to be in the camp of "I don't care if something fails".
This usually results in code, for which one needs a debugger (at the customer site) to find out, why suddenly something is not working anymore.
Also potentially people which are doing software "engineering" in this way, do not use very complex code. E.g. one would be unable to write code, which relies on the fact that it is only executed, if all n resources it relies on have been successfully allocated (while using RAII for these resources).
Thus: Such coding would result in either:
an unmanageable amount of code for error handling
an unmanageable amount of code to avoid executing code, which relies on successful allocation of some resources
no error handling and thus considerable higher amount of support and developer time
Note, that I'm talking about modern code, loading customer-provided dlls on demand and using child processes. There are many interfaces on which something can fail. I'm not talking about some replacement for grep/more/ls/find.

When and how to catch exceptions

I am working on a code-base with a bunch of developers who aren't primarily Computer Science or Software Engineering (Mostly Computer Engineering)
I am looking for a good article about when exceptions should be caught and when one should try to recover from them. I found an article a while ago that I thought explained things well, but google isn't helping me find it again.
We are developing in C++. Links to articles are an acceptable form of answer, as are summaries with pointers. I'm trying to teach here, so tutorial format would be good. As would something that was written to be accessible to non-software engineers. Thanks.
Herb Sutter has an excellent article that may be useful to you. It does not answer your specific question (when/how to catch) but does give a general overview and guidelines for handling exceptional conditions.
I've copied his summary here verbatim
Distinguish between errors and
nonerrors. A failure is an error if
and only if it violates a function's
ability to meet its callees'
preconditions, to establish its own
postconditions, or to reestablish an
invariant it shares responsibility for
maintaining. Everything else is not an
error.
Ensure that errors always leave your
program in a valid state; this is the
basic guarantee. Beware of
invariant-destroying errors
(including, but not limited to,
leaks), which are just plain bugs.
Prefer to additionally guarantee that
either the final state is either the
original state (if there was an error,
the operation was rolled back) or
intended target state (if there was no
error, the operation was committed);
this is the strong guarantee.
Prefer to additionally guarantee that
the operation can never fail. Although
this is not possible for most
functions, it is required for
functions such as destructors and
deallocation functions.
Finally, prefer to use exceptions
instead of error codes to report
errors. Use error codes only when
exceptions cannot be used (when you
don't control all possible calling
code and can't guarantee it will be
written in C++ and compiled using the
same compiler and compatible compile
options), and for conditions that are
not errors.
Read the chapter "Exception Handling" from the Book
Thinking in C++, Volume 2  - Bruce Eckel
May be this MSDN section will help you...
The most simplistic advice:
If you don't know whether or not catching an exception, don't catch it and let it flow, someone will at one point.
The point about exceptions is that they are exceptional (think std::bad_alloc). Apart from some weird uses for "quick exit" of deeply nested code blocks (that I don't like much), exceptions should be used only when you happen to remark something that you have no idea how to deal with.
Let's pick examples:
file = open('littlefile.txt', open.mode.Read)
It does seem obvious, to me, that this may fail, and in a number of conditions. While reporting the cause of failure is important (for accurate diagnostic), I find that throwing an exception here is NOT good practice.
In C++ I would write such a function as:
boost::variant<FileHandle,Error> open(std::string const& name, mode_t mode);
The function may either return a file handle (great) or an error (oups). But since it's expected, better deal with it now. Also it has the great advantage of being explicit, looking at the signature means that you know what to expect (not talking about exception specifications, it's a broken feature).
In general I tend to think of these functions as find functions. When you search for something, it is expected that the search may fail, there is nothing exceptional here.
Think about the general case of an associative container:
template <typename Key, typename Value>
boost::optional<Value const&> Associative::GetItem(Key const& key) const;
Once again, thanks to Boost, I make it clear that my method may (or not) return the expected value. There is no need for a ElementNotFound exception to be thrown.
For yet another example: user input validation is expected to fail. In general, inputs are expected to be hostile / ill formed / wrong. No need for exceptions here.
On the other hand, suppose my software deal with a database and cannot possibly run without it. If the database abstraction layer loses the connection to the database and cannot establish a new one, then it makes sense to raise an exception.
I reserve exceptions for technical issues (lost connection, out of memory, etc...).

Embedded C++ : to use exceptions or not?

I realize this may be subjective, so will ask a concrete question, but first, background:
I have always been an embedded software engineer, but usually at Layer 3 or 2 of the OSI stack. I am not really a hardware guy. I have generally always done telecoms products, usually hand/cell-phones, which generally means something like an ARM 7 processor.
Now I find myself in a more generic embedded world, in a small start-up, where I might move to "not so powerful" processors (there's the subjective bit) - I cannot predict which.
I have read quite a bit about debate about exception handling in C++ in embedded systems and there is no clear cut answer. There are some small worries about portability and a few about run-time, but it mostly seems to come down to code size (or am i reading the wrong debates?).
Now I have to make the decision whether to use or forego exception handling - for the whole company, for ever (it's going into some very core s/w).
That may sound like "how long is a piece of string", but someone might reply "if your piece of string is an 8051, then don't. If, OTOH, it is ...".
Which way do I jump? Super-safe & lose a good feature, or exceptional code and maybe run into problems later?
In terms of performance, my understanding is that exceptions actually reduce the size and increase the performance of the normal execution paths of code, but make the exceptional/error paths more expensive. (often a lot more expensive).
So if your only concern is performance, I would say don't worry about later. If today's CPU can handle it, then tomorrows will as well.
However. In my opinion, exceptions are one of those features that require programmers to be smarter all of the time than programmers can be reasonably be expected to be. So I say - if you can stay away from exception based code. Stay away.
Have a look at Raymond Chen's Cleaner, more elegant, and harder to recognize. He says it better than I could.
The choice of whether to use exceptions or not should really lie with whether they are going to fit your program's problem domain well or not.
I've used C++ exceptions extensively, both in retrofitting into old C code, and in some newer code. (HINT: Don't try to re-fit 20 year old C code that was written in a low memory environment with all manner of inconsistent exceptions. It's just a nightmare).
If your problem is one that lends itself to handling all the errors in one spot (say, a TCP/IP server of some sort, where every error condition is met with 'break down the connection and try again'), then exceptions are good - you can just throw an exception anywhere and you know where and how it will be handled.
If, on the other hand, your problem doesn't lend itself to central error handling, then exceptions are a ROYAL pain, because trying to figure out where something is (or should be) handled can easily become a Sisyphean task. And it's really hard to see the problem just by looking at the code. You instead have to look at the call trees for a given function and see where that function's exceptions are going to end up, in order to figure out if you have a problem.
The most problem with exceptions -- they don't have predictable time of execution.
Thus they are not suitable for hard real-time applications (and I guess most embedded application doesn't fall in this category).
The second is (possible) increasing of binary's size.
I would propose you reading of Technical Report on C++ Performance which specifically addresses topics that you are interested in: using C++ in embedded (including hard real-time systems) and how exception-handling usually implemented and which overhead it has.
I'd say use exceptions appropriately if the runtime environment supports them. Exceptions to handle extraordinary conditions are fine, and can cause little overhead depending on the implementation. Some environments don't support them, especially in the embedded world. If you ban them, be careful to explain why. I once had a guy that, when told not to use exceptions, did a divide by zero instead. Not exactly what we had in mind.
I think the problem is that many people voice their opinion without having a solid understanding of how exception handling in C++ works.
I have recently started at a new company, and there is consensus that we should not use exceptions, because we can't test them, because nondeterministic behaviour, etc etc. All wrong, of course.
When we talk about the overhead of having exception handling used in the code, we need to carefully consider overhead on top of what? Granted it comes at a cost, but that is the cost of alternative? Say we are using return error codes. In such scenario HALF of the if() statements in the source code will be dedicated to testing error codes and forwarding them up the call stack. Not making this up, actual metric of the codebase I'm looking at. And most of it is to deal with a) events that can't pretty much ever happen, like not having memory at the start of an embedded application and b) events that if they actually happen, we can not do anything about anyway, other than shutdown.
In this case introduction of exception handling would significantly reduce complexity of the code, separating handling of rare events from the business as usual logic. And saves ton's of overhead, because the error code checking is happening all the time. Further, it significantly reduces the size of the code. Think how much effort is needed to propagate error codes up the stack through 10 different functions, until we get somewhere where we can officially bail. Using the exception handling you can bypass the 10 intermediary levels of functions, and go straight to where we can deal with it.

How are exceptions implemented under the hood? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Just about everyone uses them, but many, including me simply take it for granted that they just work.
I am looking for high-quality material. Languages I use are: Java, C, C#, Python, C++, so these are of most interest to me.
Now, C++ is probably a good place to start since you can throw anything in that language.
Also, C is close to assembly. How would one emulate exceptions using pure C constructs and no assembly?
Finally, I heard a rumor that Google employees do not use exceptions for some projects due to speed considerations. Is this just a rumor? How can anything substantial be accomplished without them?
Thank you.
Exceptions are just a specific example of a more general case of advanced non-local flow control constructs. Other examples are:
notifications (a generalization of exceptions, originally from some old Lisp object system, now implemented in e.g. CommonLisp and Ioke),
continuations (a more structured form of GOTO, popular in high-level, higher-order languages),
coroutines (a generalization of subroutines, popular especially in Lua),
generators à la Python (essentially a restricted form of coroutines),
fibers (cooperative light-weight threads) and of course the already mentioned
GOTO.
(I'm sure there's many others I missed.)
An interesting property of these constructs is that they are all roughly equivalent in expressive power: if you have one, you can pretty easily build all the others.
So, how you best implement exceptions depends on what other constructs you have available:
Every CPU has GOTO, therefore you can always fall back to that, if you must.
C has setjmp/longjmp which are basically MacGyver continuations (built out of duct-tape and toothpicks, not quite the real thing, but will at least get you out of the immediate trouble if you don't have something better available).
The JVM and CLI have exceptions of their own, which means that if the exception semantics of your language match Java's/C#'s, you are home free (but if not, then you are screwed).
The Parrot VM as both exceptions and continuations.
Windows has its own framework for exception handling, which language implementors can use to build their own exceptions on top.
A very interesting use case, both of the usage of exceptions and the implementation of exceptions is Microsoft Live Lab's Volta Project. (Now defunct.) The goal of Volta was to provide architectural refactoring for Web applications at the push of a button. So, you could turn your one-tier web application into a two- or three-tier application just by putting some [Browser] or [DB] attributes on your .NET code and the code would then automagically run on the client or in the DB. In order to do that, the .NET code had to be translated to JavaScript source code, obviously.
Now, you could just write an entire VM in JavaScript and run the bytecode unmodified. (Basically, port the CLR from C++ to JavaScript.) There are actually projects that do this (e.g. the HotRuby VM), but this is both inefficient and not very interoperable with other JavaScript code.
So, instead, they wrote a compiler which compiles CIL bytecode to JavaScript sourcecode. However, JavaScript lacks certain features that .NET has (generators, threads, also the two exception models aren't 100% compatible), and more importantly it lacks certain features that compiler writers love (either GOTO or continuations) and that could be used to implement the above-mentioned missing features.
However, JavaScript does have exceptions. So, they used JavaScript Exceptions to implement Volta Continuations and then they used Volta Continuations to implement .NET Exceptions, .NET Generators and even .NET Managed Threads(!!!)
So, to answer your original question:
How are exceptions implemented under the hood?
With Exceptions, ironically! At least in this very specific case, anyway.
Another great example is some of the exception proposals on the Go mailing list, which implement exceptions using Goroutines (something like a mixture of concurrent coroutines ans CSP processes). Yet another example is Haskell, which uses Monads, lazy evaluation, tail call optimization and higher-order functions to implement exceptions. Some modern CPUs also support basic building blocks for exceptions (for example the Vega-3 CPUs that were specifically designed for the Azul Systems Java Compute Accelerators).
Here is a common way C++ exceptions are implemented:
http://www.codesourcery.com/public/cxx-abi/abi-eh.html
It is for the Itanium architecture, but the implementation described here is used in other architectures as well. Note that it is a long document, since C++ exceptions are complicated.
Here is a good description on how LLVM implements exceptions:
http://llvm.org/docs/ExceptionHandling.html
Since LLVM is meant to be a common intermediate representation for many runtimes, the mechanisms described can be applied to many languages.
In his book C Interfaces and Implementations: Techniques for Creating Reusable Software, D. R. Hanson provides a nice implementation of exceptions in pure C using a set of macros and setjmp/longjmp. He provides TRY/RAISE/EXCEPT/FINALLY macros that can emulate pretty much everything C++ exceptions do and more.
The code can be perused here (look at except.h/except.c).
P.S. re your question about Google. Their employees are actually allowed to use exceptions in new code, and the official reason for the ban in old code is because it was already written that way and it doesn't make sense to mix styles.
Personally, I also think that C++ without exceptions isn't the best idea.
C/C++ compilers use the underlying OS facilities for exception handling. Frameworks like .Net or Java also rely, in the VM, on the OS facilities. In Windows for instance, the real heavy lifting is done by SEH, the Structured Exception Handling infrastructure. You should absolutely read the old reference article: A Crash Course on the Depths of Win32™ Structured Exception Handling.
As for the cost of not using exceptions, they are expensive but compared to what? Compared to return error codes? After you factor in the cost of correctness and the quality of code, exceptions will always win for commercial applications. Short of few very critical OS level functions, exceptions are always better overall.
An last but not least there is the anti-pattern of using exceptions for flow control. Exceptions should be exceptional and code that abuses exceptions fro flow control will pay the price in performance.
The best paper ever written on the implementation of exceptions (under the hood) is Exception Handling in CLU by Barbara Liskov and Alan Snyder. I have referred to it every time I've started a new compiler.
For a somewhat higher-level view of an implementation in C using setjmp and longjmp, I recommend Dave Hanson's C Interfaces and Implementations (like Eli Bendersky).
setjmp() and longjmp() usually.
Exception catching does have a non-trivial cost, but for most purposes it's not a big deal.
The key thing an exception implementation needs to handle is how to return to the exception handler once an exception has been thrown. Since you may have made an arbitrary number of nested function calls since the try statement in C++, it must unwind the call stack searching for the handler. However implemented, this must incur the code size cost of maintaining sufficient information in order to perform this operation (and generally means a table of data for calls that can take exceptions). It also means that the dynamic code execution path will be longer than simply returning from functions calls (which is a fairly inexpensive operation on most platforms). There may be other costs as well depending on the implementation.
The relative cost will vary depending on the language used. The higher-level language used, the less likely the code size cost will matter, and the information may be retained regardless of whether exceptions are used.
An application where the use of exceptions (and C++ in general) is often avoided for good reasons is embedded firmware. In typical small bare metal or RTOS platforms, you might have 1MB of code space, or 64K, or even smaller. Some platforms are so small, even C is not practical to use. In this kind of environment, the size impact is relevant because of the cost mentioned above. It also impacts the standard library itself. Embedded toolchain vendors will often produce a library without exception capability, which has a huge impact on code size. Highly optimizing compilers may also analyze the callgraph and optimize away needed call frame information for the unwind operation for considerable space reduction. Exceptions also make it more difficult to analyze hard real-time requirements.
In more typical environments, the code size cost is almost certainly irrelevant and the performance factor is likely key. Whether you use them will depend on your performance requirements and how you want to use them. Using exceptions in non-exceptional cases can make an elegant design, but at a performance cost that may be unacceptable for high performance systems. Implementations and relative cost will vary by platform and compiler, so the best way to truly understand if exceptions are a problem is to analyze your own code's performance.
C++ code at Google (save for some Windows-specific cases) don't use exceptions: cfr the guidelines, short form: "We do not use C++ exceptions". Quoting from the discussion (hit the arrow to expand on the URL):
Our advice against using exceptions is
not predicated on philosophical or
moral grounds, but practical ones.
Because we'd like to use our
open-source projects at Google and
it's difficult to do so if those
projects use exceptions, we need to
advise against exceptions in Google
open-source projects as well. Things
would probably be different if we had
to do it all over again from scratch.
This rule does not apply to Google code in other languages, such as Java and Python.
Regarding performance - sparse use of exceptions will probably have negligible effects, but do not abuse them.
I have personally seen Java code which performed two orders of magnitude worse than it could have (took about x100 the time) because exceptions were used in an important loop instead of more standard if/returns.
Some runtimes like the Objective-C runtime have zero-cost 64-bit exceptions. What that means is that it doesn't cost anything to enter a try block. However, this is quite costly when the exception is thrown. This follows the paradigm of "optimize for the average case" - exceptions are meant to be exceptional, so it is better to make the case when there are no exceptions really fast, even if it comes at the cost of significantly slower exceptions.

C++ - Arguments for Exceptions over Return Codes

I'm having a discussion about which way to go in a new C++ project. I favor exceptions over return codes (for exceptional cases only) for the following reasons -
Constructors can't give a return code
Decouples the failure path (which should be very rare) from the logical code which is cleaner
Faster in the non-exceptional case (no checking if/else hundreds of thousands of times)
If someone screws up the return code settings (forgets to return FAIL) it can take a very long time to track down.
Better information from the message contained in the error. (It was pointed out to me that a return enum could do the same for error codes)
From Jared Par Impossible to ignore without code to specifically designed to handle it
These are the points I've come up with from thinking about it and from google searches. I must admit to being predisposed to exceptions having worked in C# for the past couple of years. Please post further reasons for using exceptions over return codes. For those who prefer return codes, I would also be willing to listen to your reasoning. Thanks
I think this article sums it up.
Arguments for Using Exceptions
Exceptions separate error-handling code from the normal program flow and thus make the code more readable, robust and extensible.
Throwing an exception is the only clean way to report an error from a constructor.
Exceptions are hard to ignore, unlike error codes.
Exceptions are easily propagated from deeply nested functions.
Exceptions can be, and often are, user defined types that carry much more information than an error code.
Exception objects are matched to the handlers by using the type system.
Arguments against Using Exceptions
Exceptions break code structure by creating multiple invisible exit points that make code hard to read and inspect.
Exceptions easily lead to resource leaks, especially in a language that has no built-in garbage collector and finally blocks.
Learning to write exception safe code is hard.
Exceptions are expensive and break the promise to pay only for what we use.
Exceptions are hard to introduce to legacy code.
Exceptions are easily abused for performing tasks that belong to normal program flow.
The best case I've heard for preferring return codes over exceptions is simply this:
Writing exception-safe code is hard [in C++].
With a great deal of recent experience in C# myself, I can empathize with your desire to use exceptions, but unfortunately C++ isn't C#, and a lot of things that we can get away with in C# can be ultimately deadly in C++.
A good summation of the case for and against can be found in Google's style guidelines. In short:
Pros:
Exceptions allow higher levels of an application to decide how to
handle "can't happen" failures in
deeply nested functions, without the
obscuring and error-prone bookkeeping
of error codes.
Exceptions are used by most other modern languages. Using them in
C++ would make it more consistent with
Python, Java, and the C++ that others
are familiar with.
Some third-party C++ libraries use exceptions, and turning them off
internally makes it harder to
integrate with those libraries.
Exceptions are the only way for a constructor to fail. We can simulate
this with a factory function or an
Init() method, but these require heap
allocation or a new "invalid" state,
respectively.
Exceptions are really handy in testing frameworks.
Cons:
When you add a throw statement to an existing function, you must
examine all of its transitive callers.
Either they must make at least the
basic exception safety guarantee, or
they must never catch the exception
and be happy with the program
terminating as a result. For instance,
if f() calls g() calls h(), and h
throws an exception that f catches, g
has to be careful or it may not clean
up properly.
More generally, exceptions make the control flow of programs difficult
to evaluate by looking at code:
functions may return in places you
don't expect. This results
maintainability and debugging
difficulties. You can minimize this
cost via some rules on how and where
exceptions can be used, but at the
cost of more that a developer needs to
know and understand.
Exception safety requires both RAII and different coding practices.
Lots of supporting machinery is needed
to make writing correct exception-safe
code easy. Further, to avoid requiring
readers to understand the entire call
graph, exception-safe code must
isolate logic that writes to
persistent state into a "commit"
phase. This will have both benefits
and costs (perhaps where you're forced
to obfuscate code to isolate the
commit). Allowing exceptions would
force us to always pay those costs
even when they're not worth it.
Turning on exceptions adds data to each binary produced, increasing
compile time (probably slightly) and
possibly increasing address space
pressure.
The availability of exceptions may encourage developers to throw them
when they are not appropriate or
recover from them when it's not safe
to do so. For example, invalid user
input should not cause exceptions to
be thrown. We would need to make the
style guide even longer to document
these restrictions!
I suggest reading through and understanding the pros and cons, then making a decision for your own project based on these. You don't have the same software that google has, so what makes sense for them may not make sense for you (which is why I omitted their conclusion).
IMHO, the #1 reason to prefer exceptions over return codes is you can't silently ignore an exception. Doing so requires at least a minimum amount of extra code.
Use exceptions for exceptional error conditions. You have some good arguments for, and I'd like to attack some arguments against.
First, the standard C++ library uses exceptions itself, all over the place. You can't use container classes or iostreams without having them present. Since a lot of the useful features are going to use them, trying to get along without them is going to present a lot of problems.
Second, it isn't hard to write exception-safe code once you've learned how to do it. It requires consistent RAII, but that's how you should write anyway. You should adopt a construct-commit approach, but that is frequently an advantage, and avoids some subtle bugs. (For example, the self-assignment problem disappears entirely with a copy-swap approach.) In my experience, exception-safe code looks better in general. It is something C++ programmers have to learn, but there's lots of things C++ programmers have to learn, and this isn't that much more.
Third, provided you limit exceptions to exceptional cases, there should be minimal effects on performance. And, as Pavel Minaev has pointed out, if you have to pass error codes back with results, there's the possibility of effects on performance, since C++ isn't set up for easy returns of multiple values.
Fourth, it is indeed difficult to make older code exception-safe. However, this is a new project.
So, I see no good reasons not to throw exceptions in exceptional circumstances, and plenty of reasons to do so.
As a general rule. when recovery is possible and expected then use return codes.
When recovery is not possible or not desired then use exceptions.
Error handling is difficult, writing clean code with and without exceptions is - difficult.
As this is a new project, you don't have to worry about making old code exception safe, however you do have to worry about writing clean clear code.
Do so by using exceptions where appropriate.
Faster in the non-exceptional case (no checking if/else hundreds of thousands of times)
In the non-exceptional case, it's a single comparison to determine that E_SUCCESS was returned.
If someone screws up the return code settings (forgets to return FAIL) it can take a very long time to track down.
If someone fails to check the exceptions, it can be difficult to notice until you actually get an exception thrown there. If you're dealing with error codes, you know just by looking at it whether they're checking for them or not.
Use what makes sense. I think both have a place. There are situations where error codes are nearly impossible to use (returning failure from a constructor, for example)
Other times, error codes are just more convenient. They're easier to deal with in cases where you expect them to happen. Exceptions are for exceptional errors - the ones that aren't supposed to happen, but might do so once in a blue moon. Error codes are a lot more convenient for errors that are expected to happen regularly, and can be handled locally. Exceptions are most useful in cases where the error must be handled further up the call stack.
Also, exceptions aren't necessarily faster in the non-exceptional case. Often, they require extra exception handling code in function prolog and epilogs which has to be executed every time the function is called, whether or not it throws an exception.
Since many others have already provided the technical reasons for using exceptions over error codes, I will give a practical one.
I work on a complex system which uses return codes instead of exceptions. Now, this is very well designed code, but I would bet that, on average, about 70% of the code in every function is error handling code. A typically function looks something like this:
long Foo( )
{
long retCode = MoveStage( );
if ( retCode != RetCode_OK )
{
logger->LogError( __LINE__, __FILE__, "some message" );
return( retCode );
}
int someConfigVar = 0;
long retCode = GetConfigVar( "SomeVarName", someConfigVar );
if ( retCode != RetCode_OK )
{
logger->LogError( __LINE__, __FILE__, "some message" );
return( retCode );
}
long retCode = DoSomething( );
if ( retCode != RetCode_OK )
{
logger->LogError( __LINE__, __FILE__, "some message" );
return( retCode );
}
// and on and on and on...
}
The code is full of this and is hard to follow. On top of that, in many places the return code is ignored completely because we know that the call will not fail. Every function returns a ret code, so what you would normally return as the output of the function has to be returned as an out parameter. Also, all of these functions just return the retCode on error, so we just bubble that damn retCode to the top if something bad happens. You cannot centralize your error handling strategy this way, it becomes a messy headache.
It is very hard to write exception safe code. A completely contrived example is :-
void Class::Method()
{
i++;
SomeCallThatMightThrow();
j++;
}
Replace i++ and j++ with any two variables, resources, states that must remain synchronous. Garbage collection saved us from having to remember to pair our new's and deletes. Ironically, old fashioned explicit return code testing saves us from having to carefully analyse every function that might throw exceptions to check that they havn't screwed with the post-conditions.
One of the things I like about C++ is that it's very easy to think how the higher-level features might be implemented in terms of C features (which are easy to understand in terms of assembly). Exceptions for C++ break this mold. To get this level of understanding I have to do a lot. Just read this and you'll spend a lot of time scratching your head before you understand it.
Furthermore, exceptions require you to have good discipline making your code exception safe, and resource leak free. This means using RAII for anything that holds a resource ..
Additionally, exceptions have been shown when I have measured them to be a many, many orders of magnitude slower compared to a simple return code.
Well then they say you should only throw in exceptional circumstances, but how do you communicate the non-exceptional, expected, often-occuring errors. Well return codes of course! :)
I don't see how the benefits are worth it.
Constructors can't give a return code
(except if you are possibly throwing exceptions in a constructor you are in for a world of hurt)
Decouples the failure path (which should be very rare) from the logical code which is cleaner
(Opens up a much wider failure path. C++ exceptions are not like C# at all. I love C# exceptions. C++ exceptions are worse than useless. Partly due to implementation, partly due to what c++ is and isn't)
Faster in the non-exceptional case (no checking if/else hundreds of thousands of times)
(Not really. You have to check the same number of errors no matter what, you just don't see where they get checked. Also, there are errors that matter and ones that don't or at least matter to your code, so you don't have to check every single thing (do you check to see if new threw an error?))
If someone screws up the return code settings (forgets to return FAIL) it can take a very long time to track down.
(I'll take a million such errors over any one of the common errors that come about with C++ exceptions)
Better information from the message contained in the error. (It was pointed out to me that a return enum could do the same for error codes)
(Well, how do you implement your error handling? That's up to you, isn't it? You can have exceptions that give no useful information or error codes that log out extemsive data on failure. In C++ they seem to never give useful info in the cases you really want them to)
From Jared Par Impossible to ignore without code to specifically designed to handle it
(Sure, but this code is usually useless code. It's like passing a law saying everyone has to have bug free programs. The people who don't don't obey such laws anyway and for the people who do they already handle errors where they should anyway)
As for reasons against:
Wanting your program to actually work at least some of the time.
performance.
Ideology. If it's an error we are not supposed to 'recover' from it. We either die with an error message, log and continue, or completely ignore it. If we could fix it it wouldn't be an error, but a feature...and if you use code like that intentionally no debugging tools in the world are going to save you.
Mostly one.