Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In When to use C over C++, and C++ over C? there is a statement wrt. to code size / C++ exceptions:

Jerry answers (among other points):

(...) it tends to be more difficult to produce truly tiny executables with C++. For really small systems, you're rarely writing a lot of code anyway, and the extra (...)

to which I asked why that would be, to which Jerry responded:

the main thing is that C++ includes exception handling, which (at least usually) adds some minimum to the executable size. Most compilers will let you disable exception handling, but when you do the result isn't quite C++ anymore. (...)

which I do not really doubt on a technical real world level.


Therefore I'm interested (purely out of curiosity) to hear from real world examples where a project chose C++ as a language and then chose to disable exceptions. (Not just merely "not use" exceptions in user code, but disable them in the compiler, so that you can't throw or catch exceptions.) Why does a project chose to do so (still using C++ and not C, but no exceptions) - what are/were the (technical) reasons?


Addendum: For those wishing to elaborate on their answers, it would be nice to detail how the implications of no-exceptions are handled:

  • STL collections (vector, ...) do not work properly (allocation failure cannot be reported)
  • new can't throw
  • Constructors cannot fail
share

locked by World Engineer Sep 5 '13 at 14:33

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

closed as too broad by gnat, GlenH7, World Engineer Sep 5 '13 at 14:33

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
JSF C++. Jets and exceptions don't mix. –  Coder Jun 2 '12 at 21:24
1  
Some enlightening info about problems with exceptions (and C++ in general) 250bpm.com/blog:4 –  Ambroz Bizjak Jun 3 '12 at 22:41
1  
@AmbrozBizjak - I'll quote DeadMG from a comment to the post you link to: quote:"It appears to me that you do not understand exceptions." I agree. The author clearly made a mess of exception handling, looking at the examples he gives in that post. –  Martin Ba Jun 4 '12 at 9:13

11 Answers 11

A good example is kernel mode programming.

You can use C++ there for cleaner code but without exceptions. There is no runtime library for them and exception handling use too much stack memory that is very limited in the kernel (I experimented with C++ exceptions in Windows NT kernel and exception throwing and unwinding eats a half of available stack - very easy to get stack overflow and crash the whole system).

Typically you define your own new and delete operators. Also I found pretty handy a placement new and c++11 rvalue references. No STL or other C++ user-mode libraries which rely on exceptions can be used.

share

In the Joint Strike Fighter C++ coding standard by Bjarne et. al., exceptions are banned, due to the hard real-time requirements of fighter jets.

JSF++ is for hard-real time and safety-critical applications (flight control software). If a computation takes too long someone may die. For that reason, we have to guarantee response times, and we can't - with the current level of tool support - do that for exceptions. In that context, even free store allocation is banned! Actually, the JSF++ recommendations for error handling simulate the use of exceptions in anticipation of the day where we have the tools to do things right, i.e. using exceptions.

Quoted from Bjarne's C++ FAQ.

Remember, C++ probably runs the widest variety of software of all languages...

share
    
JSF++ also bans use of "new" (other than placement new) and "delete". Which is one answer to the "how do you handle new failing without exceptions" bit of the question... –  armb Aug 21 '13 at 13:57
    
@armb: Yes. See "In that context, even free store allocation is banned!" above. –  Macke Aug 22 '13 at 5:28

Google doesn't approve of exceptions in their C++ Style Guide, mostly for historical reasons:

On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions.

Given that Google's existing code is not exception-tolerant, the costs of using exceptions are somewhat greater than the costs in a new project. The conversion process would be slow and error-prone. We don't believe that the available alternatives to exceptions, such as error codes and assertions, introduce a significant burden.

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.

There is an exception to this rule (no pun intended) for Windows code.

(Editor's emphasis)

share

Almost any console game out there is in C++ with exception deactivated, even today. In fac it's the default setup for C++ compilers targeting those consoles. Sometimes some C++ features are not guaranteed to work correctly on those compilers, like multiple inheritance (I'm thinking about a very well known console default compiler for example).


Also, another example is Arduino hardware SDK usnig gcc without exception activated in C++, and other things like no STL provided.


There are some technical reasons, good or bad, whatever, it's not my advice but reasons I've heard :

  1. Most consoles are really embedded systems with limited memory and processing time. Maybe it will not be so true in future consoles, but current ones are still prety restrictive compared to a PC. Some portable consoles are erally harder to program than any smartphone, for example the NDS. Exception feature does add memory and a little bit of speed cost, even if you don't use it. You can check yourself, it's true even on PC.
  2. Video games on console can't crash. They have to be tested in a way that avoid any crash or any dead-end, any showstoper. That's why console manufacturers asks the games to be heavily checked before publication. That also mean that exception management add cost that isn't really useful in case of console game. It's better in smartphone for example because there might be some ways to recovery or the add some code to email you the problem. Closed platforms like most consoles don't allow this. So an exception system isn't really necessary after all. You "just have to make it work correctly". ;)
  3. Exception management, when you don't allow errors and crashes, means you have to implement an error management strategy. Such system might be complex enough to make someone work a lot of time to make it useful. Game developers don't have luxury to work on features that are thought to be useful in crashes...
  4. The compiler don't allow it (yet). Yes, it happen.

I think exceptions can be useful even in games but that's truee that on console games it's not really useful.


Update:

I'm adding another surprising example here: LLVM/CLang dont use exception nor RTTI for the followin reasons:

In an effort to reduce code and executable size, LLVM does not use RTTI (e.g. dynamic_cast<>) or exceptions. These two language features violate the general C++ principle of "you only pay for what you use", causing executable bloat even if exceptions are never used in the code base, or if RTTI is never used for a class. Because of this, we turn them off globally in the code.

That said, LLVM does make extensive use of a hand-rolled form of RTTI that use templates like isa<>, cast<>, and dyn_cast<>. This form of RTTI is opt-in and can be added to any class. It is also substantially more efficient than dynamic_cast<>.

CLang is well known for its speed ofr compilation and explicit errors, but also its one rare compiler that have really easy-to-follow code.

share
9  
(3): you need an error management strategy no matter what, if you're going to go along with (2). Problems will come up, and your console software needs to fail soft and gracefully. It isn't obvious to me that avoiding exceptions entirely makes that any easier. –  David Thornley Oct 10 '11 at 16:37
6  
All great examples of tightly controlled runtime environments where errors are handled properly and there are no "exceptional" events. –  Patrick Hughes Oct 10 '11 at 16:42
1  
@DavidThornley Because you assume that the console's system will manage some kind of errors, but it will not. Well maybe it will on PS3 or XBox but that will not be allowed to pass console builder's tests. Anyway, the firmware of most advanced consoles isn't as flexible as you might think. A console game need to have access to almost all the hardware of the console, so you can think about a game running on a console almost like if it was also the "OS" of the console... the more we have powerful consoles, the less it is true. So I agree with you that it seems strange for some cases. –  Klaim Oct 10 '11 at 16:45
2  
This is a good answer, I'd like to also add that even if an exception bubbled up and presented the user with an error, what is he or she supposed to do about it with a D-pad? The only real solution for the end user is a restart. –  anon Oct 11 '11 at 2:34
2  
I removed the folly example because someone on their team said on boost the NO EXCEPTION is not meant to mean "no use of exception" but "no exception to the rules". See permalink.gmane.org/gmane.comp.lib.boost.devel/231377 –  Klaim Jun 4 '12 at 17:58

Qt almost never uses exceptions. Errors in Qt are signified with error codes and signals. The officially stated reason is:

When Qt was started exceptions were not available for all the compilers that needed to be supported by Qt. Today we are trying to keep the APIs consistent, so modules that have a history of not using exceptions will generally not get new code using exceptions added.

Why does QT use so few exceptions?

Today, one common criticism of Qt is that its exception safety is not complete.

share
1  
Thanks. Good info, although I'm wondering whether most QT code bases probably have exceptions enabled in the compiler ... –  Martin Ba Jun 3 '12 at 12:44

It's kind of important in C++ library design. Often times with a C-interface it's kind of nasty to throw an exception out of your 3rd party library to the client. Point being that if your library throws, you're cutting out a set of clients who would have used it, given that it had a no-throw guarantee (for whatever reason that client has for a restriction on exceptions).

Personally I've seen exceptions abused when the team is told to "throw in an exception" whenever something not-so-terrible happens. Of course you see the error here- the exception was thrown in the code before anyone figured out what to do with it. That project had a few crashes as these deep-throws would rear out occasionally.

share

Symbian C++ (used on some Nokia mobile phones) doesn't use exceptions, at least not directly, because C++ compilers didn't reliably implement them when Symbian was first developed.

share
1  
This doesn't hold for modern versions of Symbian. Symbian TRAPs and leaves are implemented as real C++ exceptions, but EPOC32 and older versions of Symbian did rely on other means (setjmp/longjmp if I recall correctly). –  Otto Harju Oct 10 '11 at 20:10
1  
@OttoHarju: That's what I meant by "at least not directly". –  Keith Thompson Oct 10 '11 at 20:12

I /never/ use exceptions. There are a number of reasons for this, but the two main reasons are that I have never needed them to produce robust code and that they reduce the performance at runtime.

I have worked on production code that is both using and disabling exceptions - the code that allowed exceptions was uniformly worse. In some places exceptions were used for genuine flow control rather than error handling, which is very heavyweight, anti-performance and difficult to debug. In general debugging problems in the exception filled code was more difficult than in the exception-free code - partly down to the stack and intrinsic difficulties of the exception mechanism, but much more than that it was because of the lazy code that was encouraged as a result of having exception handling available.

There is nothing seriously wrong with exceptions themselves /if you don't care about performance/ and don't have time to do something properly - they are a language feature for error handling and a good substitute for a proper error handling mechanism. However, there are almost always /better/ ways to handle errors - like with your own logic (its hard to elaborate on this - it is almost common sense). If its not your error, but comes from a library (e.g. the standard library) then you have to respect the choice of exceptions or have some crash, but I'd always question that choice. I have never seen a situation where exceptions were actually the best solution.

Assertions are more debuggable, error codes are less heavyweight... between the two, if used properly, you get easier to read, debug and maintain code which is faster. Its wins all round...

share
1  
Nope. It's easier to misuse exceptions, but other than that exceptions work well. It's at least as easy to reason about, provided all your functions are exception-safe (and that's usually just a matter of using RTTI for all resources, which you should be doing anyway). Doing error codes properly can be extremely tedious, and can result in burying your program in a pile of error-handling code; in that case, exceptions are better. Remember, my doing things differently from you is not conclusive evidence that I don't care about doing things right. –  David Thornley Oct 11 '11 at 22:00
    
...as for why RTTI is bad that is a whole other story - the built-in RTTI in every compiler I have seen is trivially beatable - if you even need RTTI. Its all about context though - these things like RTTI and exceptions can be great for RAD and enterprise apps - they have no place in the world of high performance (e.g. games) computing. I've never seen a production game engine using either on any target where they could be turned off... –  jheriko Nov 30 '11 at 16:03
2  
Sorry - RAII is what I meant. If you're not using that, then not only exceptions are going to be messed up. (However, dynamic casts work very well in my work, and I do have to be concerned with performance.) –  David Thornley Nov 30 '11 at 17:35
    
Interesting topic: I think exceptions allow a more concise error handling coding but error codes are more robust because they allow to handle errors locally (you can check the return code immediately in the caller while exception can bubble up the call-stack before they are caught and sometimes they are not caught, resulting in a crash. Unless you use catch (...)). –  Giorgio Jun 3 '12 at 13:56

Jerry said: ...the result isn't quite C++ anymore, while my metaphor is that it is clearly C++, just a slightly different dialect because programs utilize other forms, conventions, and written styles.

Here are my primary reasons for disabling them:

Binary Compatibility

Crossing language and translation boundaries is not universally well defined, or undefined. If you want to guarantee your program operates within the domain of defined behavior, you will need to quarantine exceptions at module exit points.

Executable Size

Here are the binary sizes of an exception free program I wrote, built without and with exceptions enabled:

Without exceptions:

  • executable + dependencies: 330
  • final stripped executable (release build): 37

With exceptions:

  • executable + dependencies: 380
  • final stripped executable (release build): 44

Reminder: That's a collection of libraries and programs which contain zero throws/catches. The compiler flag does enable exceptions in the C++ standard library. Therefore, the cost in the real world is more than 19% seen in this example.

Compiler: apple gcc4.2 + llvm. Sizes in MB.

Speed

Despite the term "zero cost exceptions", they still add some overhead even when nothing ever throws. In the above case, it is a performance critical program (Signal Processing, Generation, Presentation, Conversions, with large data sets/signals etc.). Exceptions are not a necessary feature in this design, while performance is very important.

Program Correctness

Seems like a strange reason... If throwing is not an option, you must write relatively strict, correct, well tested programs to guarantee your program executes correctly, and that clients use the interfaces correctly (if you give me a bad argument or do not check an error code, then you deserve UB). The result? Implementation quality improves greatly and problems get fixed quickly.

Simplicity

Exception handling implementations aren't often kept up to date. They also add a lot of complexity because an implementation can have many many many exit sequences. It's simpler to read and maintain highly complex programs when they use a small set of well defined, typed, exit strategies which bubble up to and are handled by the client. In other cases, the implementations may over time implement more throws or their dependencies may introduce them. Clients cannot easily or appropriately defend against all these exits. I write and update a lot of libraries, there is frequent evolution and improvement. Attempting to keep that all in synch with exception exit sequences (in a large codebase) would not be a good use of time, and would likely add a lot of noise and cruft. Due to increased program correctness and more tests, many (certainly not all) of the potential issues/exits can be ruled out.

History/Existing Code

In some cases, they were never introduced for historical reasons. An existing codebase did not use them, changing the programs could take man-years and make it really ugly to maintain because of overlap in conventions and implementations.

Downsides

Of course, there are downsides, the biggest are: Incompatability (incl. binary) with other libraries, and the fact that you will have to implement a good amount of programs to fit this model.

share
    
+1 excellent info! (although I do not agree with the Simplicity paragraph) –  Martin Ba Oct 11 '11 at 8:56
    
It would be interesting if you only have no-fail constructors and how you handle allocation (- failure). –  Martin Ba Oct 11 '11 at 8:58
    
@Martin 1) Disagreeing is quite fine. I understand that most devs disagree with disabling exceptions for multiple reasons. For simplicity, it goes along with program correctness. Problems/invalid states simply aren't allowed to travel far. That means they check for failures and exit gracefully. jheriko's post echoes this. –  justin Oct 11 '11 at 9:08
1  
@Martin 2b) allocation is a bit more complex. First, the number of heap allocations is reduced in number and increased in size - there relatively few heap allocations to begin with. Second, allocations go through custom allocators. If an allocation is not initially provided for the allocator (e.g. malloc returns 0), the allocator enters a while (1) which has a context switch, followed by another attempt at allocation. In this codebase, it used to be that new via the allocator could return 0, but the newer implementation has been working fine. (cont) –  justin Oct 11 '11 at 9:20
2  
yes, there is a stl compatible wrapper over the custom allocator interfaces. technically, the program will not abort in release; it will introduce context switches (e.g. allow another thread to work which will hopefully free some memory), retry, and log if that fails - forever. unit tests can run for days without issue. the only real threat is huge allocations, many of which will be caught before requested. again, the system's failure rates are also on the radar at this point; the possibility exists that they will fail before the core implementation in such a scenario. –  justin Oct 11 '11 at 10:00

When you are trying to keep executable memory down. Typically done on embedded (or mobile) systems. For desktops apps its never needed however on servers it might be considered if you want as much ram as possible for the web server or for sql.

share

Perhaps in this regard, it's worth mentioning Embedded C++. Embedded C++ is a variant of C++ designed (obviously enough) for embedded systems. It's basically a proper subset of C++, with (among other things) templates, namespaces, and exception handling removed.

I should add that while EC++ made a bit of a splash when it was new, they seem to have mostly gone fairly quiet. I'm not sure if people have lost interest, or their first attempt was simply so perfect that nobody's seen any reason to mess with it for a decade or so. <closed captioning for the humor impaired>Yeah, right!</closed captioning>

share
    
Looking a the Q&A - caravan.net/ec2plus/question.html - I'd say it's pretty much dead. –  Martin Ba Oct 11 '11 at 10:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.