41

"We do not use C++ exceptions."

If you don't use exceptions, what happens when there's an error? You just let the program crash?

Taylor Nichols
  • 588
  • 2
  • 13
Mr. X
  • 419
  • 1
  • 4
  • 3
  • 34
    Please, for all that is good in the world, do not adopt the Google Code Style Guide. It's awful for modern C++ projects. [Just ignore it.](http://stackoverflow.com/questions/3312513/on-a-disadvantage-of-exceptions-in-c/3312577#3312577) – GManNickG Aug 16 '10 at 04:08
  • 4
    There is one case I can think of where exceptions are not an option (other than embedded C++ where they may not be supported) - when exposing your C++ class within a shared library through an abstract interface. In such cases, whether it be your own custom DLL (or .so), or COM interface or XPCOM interface, to name a few, you can't have exceptions crossing the interface boundary. So you have to resort to catching all exceptions and returning error codes instead. Otherwise I agree with GMan, the trouble of not using exceptions is just not worth it. – Praetorian Aug 16 '10 at 06:44
  • 9
    C doesn't have exceptions, it still lets you deal with exceptional cases. You can do the same in C++. – nos Aug 16 '10 at 07:37
  • 5
    You'd deal with errors just like you do in other languages without exceptions: lots of explicit code to check the result of every function call, and long debugging sessions when someone gets it wrong. But unless, like Google, you have an enormous body of legacy code that isn't exception-safe, you'd be crazy to write code like that. – Mike Seymour Aug 16 '10 at 11:11
  • Ah, so this is why both AddressSanitizer on Windows and Dr Memory (developed by Google employees) do not support exception handling in C++: They simply don't need it for their own projects ... – FourtyTwo Feb 20 '19 at 16:36
  • Related: https://stackoverflow.com/questions/26645035/writing-c-without-exceptions – mic Oct 28 '20 at 22:24

7 Answers7

28

No, the alternative is to do what people have done for ages in C... you return an error status code that indicates whether the function succeeded or not, and depending on the ways in which it can fail, you might have one or more out parameteters in which you indicate the way in which it failed (or you incorporate the type of failure in the error status code, again it's a case-by-case thing).

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
28

Or you could read a little further:

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 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.

Robert
  • 21,110
  • 9
  • 55
  • 65
  • 5
    why? I have read the whole c++ style guide and I fully agree with most of the remarks – Karel Bílek Aug 16 '10 at 02:29
  • 12
    @Karel: Because some of us are not adding C++ to enormous existing C codebases, and therefore should be using exceptions for reporting errors. The Google Style Guide is fine with respect to style and formatting and such, but the "We only use a subset of C++ features" pieces are simply not good ideas for new code, unless that code is for a library meant to be consumed by not-new code. – Billy ONeal Aug 16 '10 at 03:12
18

Alternatives to exceptions other than return codes:

  • LISP-style conditional handler.
  • Software signals and slots, QT-style.
  • Hardware interrupt or signal handler without a stack unwind. It's the stack unwind that is the problem with exceptions on embedded devices.
  • longjmp / setjmp
  • Callback function
  • Flag value e.g. errorno (Unix), GetLastError (Windows), glGetError (OpenGL), etc.
  • Message queue, if program is event driven
  • Mutable functor. Handler object as input-output parameter, pointer is changed on error.
  • Fibers or threads with an error resolution co-routine
  • asm __int 3 or CPU-equivalent
  • Overlay instructions or trampoline functions.

...and many more. Many of the above-listed are embedded device friendly.

lisa
  • 1,292
  • 12
  • 8
8

If you don't use exceptions by definition no code will throw an exception so it will not be needed to be caught.

It's "We do not use C++ exceptions", not "We do not catch C++ exceptions".

Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
  • 1
    Ah we do not have errors, so we do not have to handle them? You don't need exceptions to crash a program, writing to invalid memory locations after ignoring an error will do just fine. So letting your program crash is one of the alternatives to exceptions. – josefx Aug 16 '10 at 07:37
  • 2
    @josefx: in standard C++ writing to an invalid memory location is undefined behavior. The C++ standard doesn't dictate it must throw an exception, in fact on linux for example it doesn't (it sends a signal). Actually, I don't think an exception is thrown on any OS when that happens. I believe Windows optionally throws a structure exception (which is different from a C++ exception), but that's about it. – Andreas Bonini Aug 16 '10 at 12:15
  • 1
    I meant that the program is already in an invalid state after ignoring an error and the signal will most likely kill it => You let it crash. Not using Exceptions removes the buildin error handling of c++ and unhandled errors will corrupt data and cause the program to crash. – josefx Aug 16 '10 at 12:30
  • 2
    @josefx: continuing after an error will not reliably crash the program; it could just as easily corrupt more data and cause even more catastrophic failure. You can't rely on the behaviour of undefined behaviour, and if the program is in an invalid state then the only valid options are to fix it, or terminate. – Mike Seymour Aug 16 '10 at 14:20
  • 1
    @Mike Seymour I tried to refer to the questions "what happens when there's an error? You just let the program crash?" and Bininis answer stating that you don't have to catch exceptions. As in catching exceptions has nothing to do with a program crashing - it can crash even without exception handling. I tend to think in weird ways and sadly it shows in some of my comments :-(. – josefx Aug 16 '10 at 16:17
  • how to handle the errors from standard functions like std::stoi/f ? I can't control the string I am going to get but at least I should be able to handle the output of the function. – psykid Dec 08 '20 at 12:15
7

The linked style guide explains it well:

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.

It is relatively easy in C++ to create robust code without using exceptions or worrying about Exception Guarantees. With return codes and asserts, exceptions are really limited to programmer errors.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
7

If you're writing code and reach a point where you've identified an issue for which you would typically throw an exception, but wish to abide by some stipulation that exceptions won't be used, then you have to find another way to let the client code know of the error.

As many existing answers document, you could return a sentinel value (e.g. a true/false success value, an enum). This practice is widely familiar from common C functions specified by POSIX and libc, like fopen(), strstr() or printf().

Another important option is to set some internal state that they can query later. Why might you want or need to do the latter? Because some functions, crucially C++ constructors and operators, don't typically give you the opportunity to return an error code. For example, in:

  X x1(something), x2(whatever);
  fn(x1 + x2);

X::X(...) can't return anything. X::operator+ may be invoked (assuming + isn't invoked on results of conversion operators), but fn() is presumably expecting a const X& (or X&& with C++11), and operator+ needs to return an X so it works in the successful situation. You have no chance to return a distinct type of error code. class X may need to set some internal state that other code (perhaps fn(), perhaps a statement after fn() is called) tests to take appropriate action.

So, you end up with something like:

X x1(something), x2(whatever);
assert(x1.is_valid() and x2.is_valid());
X x3 = x1 + x2;
assert(x3.is_valid());
fn(x3);

Note that this error handling convention is verbose and prone to being overlooked or ignored by client coders - one of the reasons exceptions were created. An interesting variation on this is utilised by most float point hardware - certain operations like division by 0 or under/overflows may set the register to sentinel values such as Not a Number "NaN" or +/- Infinity, and then operations involving an argument in such a state propagate the state to their result. For example, x = 8 + y / 0; z = x + 2; will set z to a sentinel too. The idea here is that you can write code that calculates the correct result whenever possible, and check once before using the result to see if an error from anywhere in the calculation code invalidated that result. It works ok for maths code sometimes, particularly when you're not making branching decisions based on the current values of the variables, but unfortunately in many situations you either won't be able or won't want to make all the users of a potentially invalid object code super-defensively to handle and propagate error states.

Using C++ without exceptions serious compromises the usability, maintainability, concision and elegance of the language.

As an alternative to a total ban on exception usage, in some environments you may be able to catch all exceptions at the boundaries of your API, then return error codes or sentinel values in a "C" style. This allows better coding internally, but better interoperability externally. Sadly, sometimes any use of exceptions is impractical, as your code will execute in an environment where the exception-handling mechanisms aren't provided... perhaps inside a kernel, driver, or embedded environment with a stripped down C++-style compiler. Such an environment is not true C++ though, as it's not Standard compliant.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
4

You use the error-code-returning versions of functions and act according to the return value.

Nick Strupat
  • 4,928
  • 4
  • 44
  • 56