Comment by badlibrarian

1 day ago

If you're in a market that requires using C++, many of these decisions are made for you by the platform above you, and you're screwed. Turn on RTTI, build a fort to deflect the random exceptions they'll throw at you, and may the gods allow you to recoup your R&D before some well-intentioned yokel in some media or game vertical changes everything and requires you to change everything.

On the other hand, if you control your own destiny and care about velocity and code quality, many of these choices eventually become self-evident.

If you are messing around with the latest and greatest esoteric C++ stuff in 2026, bless you, you beautiful nerd. But it may be time to start evaluating where you are in life, and how you got here. (And if you're on a C++ committee, I revoke those blessings.)

For those who remain: if you have a C++ code base yet somehow have enough time and energy to write opinionated blog posts, it's really hard to imagine why you think you'd have a better take on this than Google.

https://google.github.io/styleguide/cppguide.html

> build a fort to deflect the random exceptions they'll throw at you

Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions.

> if you have a C++ code base yet somehow have enough time and energy to write opinionated blog posts, it's really hard to imagine why you think you'd have a better take on this than Google.

"Given that Google's existing code is not exception-tolerant [...] Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. [...] Things would probably be different if we had to do it all over again from scratch."

  • > Which is really no different from someone choosing to terminate.

    If you std::abort(), you'll get a useful stack trace in the core dump. If you crash from an unhandled exception, you don't. That's a pretty huge difference and is one of the reasons exceptions suck.

    • That's nice but it's certainly not guaranteed by anything, just something provided by your toolchain or platform. ("Core dumps" aren't even a thing in C++.)

      If you're looking for implementation-specific guarantees then you could make that happen with exceptions too. I think on GCC replacing a function like __cxa_throw might be sufficient to let you capture a stack trace?

      If you're looking for source-level-only guarantees then another option is to just replace your throw <expr> statements with one that attaches whatever extra info you want. You could literally script this to patch your external repos automatically too. Or heck, maybe you could even just define throw to be a macro that shoves your stack trace into some global variable before actually throwing.

    • > If you std::abort(), you'll get a useful stack trace in the core dump. If you crash from an unhandled exception, you don't. That's a pretty huge difference and is one of the reasons exceptions suck.

      All of this is up to the implementation in practice. The codebases I work on generally follow the pattern that exceptions may be thrown but may not be caught*, and thus they practically serve as terminate. And we absolutely get stack traces in our core dumps (Linux, both GCC and clang), and basically all of the complex debugging I do starts with a coredump stacktrace.

      * We follow this pattern for a few reasons, (1) it is generally safer for us to assume that libraries we consume (STL included) will behave as expected with exceptions enabled, (2) "don't catch exceptions" (or if you must, catch the as close-to-throw as possible) is a simple way to avoid exceptions-for-nonexceptional-cases control flow, and (3) most of the C++ codebase is exposed through bindings in Python, and propagating errors as exceptions is the only Python-friendly way to handle it.

    • > If you crash from an unhandled exception, you don't.

      .. you absolutely get a stack trace from unhandled exception in c++, that starts where the exception is thrown? At least with clang and GCC, maybe MSVC isn't able to.

      foo.cpp:

          #include <stdexcept    
          void bar() { throw std::runtime_error("boo"); }
          void foo() { bar(); }
          int main() { foo(); }
      
      

      running:

          $ g++ foo.cpp -std=c++23 -g
          $ ./a.out
          terminate called after throwing an instance of 'std::runtime_error'
            what():  boo
      
          $ coredumpctl gdb
          ...
          #7  0x00005555555551bb in bar () at foo.cpp:3
          #8  0x00005555555551da in foo () at foo.cpp:4
          #9  0x00005555555551e6 in main () at foo.cpp:5
      
      

      it's a basic example, but it's how I've always done all my debugging in C++ since forever

      2 replies →

  • > Sounds like you hate exceptions, right? In which case why do you handle them at all?

    One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are.

    My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors.

    Python is the bloody worst because I never effing know what the hell any damn function can throw or return. It’s so so frustrating.

    Error handling is a hard and unsolved problem. But I’ll take Rust results over exceptions 10,000% of the time. Not even a question.

    • Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract.

      For example, you're implementing an arithmetic operator and have reached an erroneous state, but the arithmetic type doesn't have an error value, the only way to communicate the error is by throwing. Another example: you've specified that a function must always succeed, but later on you find a case where the function cannot succeed. Instead of fixing all the possible call sites, throw an exception. All those callers could not have handled the error anyway, because they were coded under the assumption that no error would happen at that point. Throwing an exception and letting it unwind the stack way up (perhaps even all the way up to main()) is the sensible solution, because at that point you've reached a situation with no reasonable way for that code to handle.

      Saying that you prefer Result over exceptions is like saying that you prefer strings to functions. They do different things. If you like Result, nothing prevents you from implementing a C++ equivalent.

      31 replies →

    • > One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are.

      Could you please explain how exactly you know if a function might abort?

      And how you figure out exactly which error codes a function might return if it does return an error?

      And why/how your techniques for figuring out the above don't work for exceptions?

      > Python is the bloody worst because I never effing know what the hell any damn function can throw or return. It’s so so frustrating.

      No, it's pretty possible. Virtually any interesting function you call can throw AttributeError or TypeError, if nothing else, simply by virtue of you passing an object of the wrong type or behavior.

      "But I don't mean those particular exceptions! I don't care about them." Well yeah that's kind of the point. If you can pretend that problems you don't know how to handle don't exist, then you can pretend the same for exceptions and errors. You're not supposed to care about the entire universe of possible error conditions; it's not only impossible but also you wouldn't be able to handle all of them anyway. You handle everything you can reasonably handle and then let the rest propagate, not the other way around. Same for error codes and exceptions.

      "But the documentation would tell me which error codes I care about!" Well it can do that for exceptions too. If the documentation sucks then bring it up with the API developer not the language developer.

      > But I’ll take Rust results over exceptions 10,000% of the time. Not even a question.

      Sure, feel free to do that. Or use error codes in C++, whatever you prefer. Not like I'm trying to turn this into a Rust vs. C++ debate.

      2 replies →

> it's really hard to imagine why you think you'd have a better take on this than Google.

Do you mean this as an appeal to Google being the home to great talent, or more as an endorsement of the specific guidance provided by this specific style guide, Google or no?

Because if the former, I think I do almost everything better in my context than Google would. It would be hard not to considering the difference in organizational scale.

I interview C++ developers often, and here in 2026 it seems pretty much everyone is using modern (C++20 and up) language versions.

Maybe the tooling finally caught up.