Exceptionally Bad: The Misuse of Exceptions in C++ & How to Do Better - Peter Muldoon - CppCon 2023

  Рет қаралды 24,363

CppCon

CppCon

4 ай бұрын

cppcon.org/
---
Exceptionally Bad: The Misuse of Exceptions in C++ & How to Do Better - Peter Muldoon - CppCon 2023
github.com/CppCon/CppCon2023
Exceptions were originally heralded as a new modern way to handle errors. However the C++ community is split as to whether exceptions are useful or should be banned outright. It has not helped the pro-exception lobby that in their enthusiasm to embrace exceptions, a lot of code has been written that puts exceptions in a bad light.
In this talk, We will present the original intent/history of exceptions and a brief overview of how exception mechanics work and how they circumvent the usual stack return mechanism to set the stage. we will then examine the philosophy of using exceptions and then the many cases of exception misuse including resource management, retries, hierarchies, data passing and control flow to name but a few.
For each case, we will then suggest better ways to handle each specific situation. In many cases, exceptions are often dropped in favor of some other more appropriate paradigm.
Finally, we will introduce situations that can truly benefit from exceptions and what a model exception class might look like.
---
Peter Muldoon
Pete Muldoon has been using C++ since 1991. Pete has worked in Ireland, England and the USA and is currently employed by Bloomberg as a senior Engineering Lead. A consultant for over 20 years prior to joining Bloomberg, Peter has worked on a broad range of projects and code bases in a large number of companies both tech and finance. Such broad exposure has, over time, shown what works and what doesn't for large scale engineering projects. He's a proponent of applied engineering principles, elegant solutions and expressive code.
---
Videos Filmed & Edited by Bash Films: www.BashFilms.com
KZbin Channel Managed by Digital Medium Ltd: events.digital-medium.co.uk
---
Registration for CppCon: cppcon.org/registration/
#cppcon #cppprogramming #cpp #exceptions

Пікірлер: 66
@origamibulldoser1618
@origamibulldoser1618 4 ай бұрын
Bjarne is the man for "taking the stand" after this talk.
@dansanger5340
@dansanger5340 4 ай бұрын
If everybody is getting C++ exceptions wrong, which they apparently are, sometimes even in the standard library (throwing exceptions for parse errors or file errors ?!?!?!), then maybe the problem is with exceptions, not the users of the language.
@arisweedler4703
@arisweedler4703 4 ай бұрын
Great talk. Entertaining and concise I work on an exception-free code base, and we heavily use ADTs (algebraic data types: optional/expected/variant) to pass errors up the stack. This talk made me realize: we rarely have deep backtrackes, so we don’t really miss exceptions. But if we DID have deeper backtraces, maybe we would want them
@binary132
@binary132 4 ай бұрын
Yeah, deep variant (Result) stacks in Rust get super unwieldy.
@fmatthew5876
@fmatthew5876 3 ай бұрын
In one of my previous jobs. Adding a stacktrace to the systems base exception class was the single biggest productivity booster I added in one PR. Massive difference in debugging after that.
@ABaumstumpf
@ABaumstumpf Ай бұрын
Uh i SOOOO hate it that in our codebase we have some generated lookup-classes and they are responsible for most of the exceptions: "toID", "toString" and such functions that throw and the exception has a stacktrace..... just that the ONLY readable filename/linenumber is of the function it self and it neither traces nor stores the passed in parameter. So all you get is an exception that tells you that toID has thrown.
@NickDrian
@NickDrian 4 ай бұрын
amazing content and well delivered. thanks!
@CppCon
@CppCon 4 ай бұрын
Congratulations Peter! Top third most watched recent tech talk of the week: techtalksweekly.substack.com/p/tech-talks-weekly-1-tdd-and-ddd-from
@anatheistsopinion9974
@anatheistsopinion9974 4 ай бұрын
I'm definitely going to use the omega exception class.
@emiliancioca
@emiliancioca 4 ай бұрын
Fantastic talk! Coming from the GameDev world, I have had little experience with exceptions but this talk made me much more confident in them. Looking forward to putting this into practice in some none-engine code :)
@PixelPulse168
@PixelPulse168 4 ай бұрын
Exactly. None-engine code. OR don't use it at all in games🤭
@X_Baron
@X_Baron 4 ай бұрын
I'd be interested in the details of and rationale behind the special stack unwinding, and what are the recent efforts to mitigate the costs.
@kuhluhOG
@kuhluhOG 2 ай бұрын
As the speaker said, exceptions should be used for rare cases, or as some people say "for the truly exceptional". Here's a problem with that: Who determines what's "truly exceptional" or "rare"? It depends on your problem domain. And that also kinda means that if you want a general purpose library, that you can't really do that decision for anything but stuff which will (or should) never reach your users code. Anything else can under their circumstances be something they expect to happen, something usual. And since exceptions are expensive, if your decided to use them, you may make your library unusable for certain people because they would start hitting that exception often.
@about2mount
@about2mount Ай бұрын
How you should handle exceptions. if(true){ do code; }else{ cout
@thunder852za
@thunder852za 4 ай бұрын
first 7 minutes in and I am loving it.
@KX36
@KX36 4 ай бұрын
if I ever make a joke language, functions will only be able to return error codes, to return data you'd have to throw it.
@MarcEspie
@MarcEspie 3 ай бұрын
There are ways to deal with out-of-memory, specifically by having a preallocated pool you can free up for "disaster recovery" (which is usually enough to make sure your persistent files/databases are in a consistent system before dying a clean death).
@johnmcleodvii
@johnmcleodvii 3 ай бұрын
And in some programs may always be out of memory, but there is a pool of potential useful but discardable data. I was working on an image editor with an undo stack. The undo stack tended to allocate all available memory after awhile. We wrote our own function that the memory allocator called when out of memory instead of using the default that threw the out of memory exception. This kept most of the changes localized. It did mean that the undo stack had to be aware that the objects that were in pointed to might be gone.
@MarcEspie
@MarcEspie 3 ай бұрын
@@johnmcleodvii looks like a very nice solution to that problem indeed !
@kuhluhOG
@kuhluhOG 2 ай бұрын
and sometimes you only get this error because what you tried to allocate was stupidly large was "fun" to debug until I found out that the blob the program was trying to allocate was over a terrabyte
@ABaumstumpf
@ABaumstumpf Ай бұрын
But for exceptions that is the rare exception. And in those cases you are very well aware of why it happened and how to handle it, so absolutely no reason for that to have an influence on the standard-provided types.
@jdkoftinoff
@jdkoftinoff 4 ай бұрын
I met lots of developers who say they don't use exceptions in c++ but since they don't compile their libc++ or libstdc++ with -fno-exceptions they actually are using exceptions but just don't handle them. This was a good talk. One reason however I like to not have main() or thread's do catch(...) is because an unhandled exception in my mind is a logic error and relying on ... to catch it means you forgot to handle it at the appropriate spot. So in this case you will instead get std::terminate() called which typically is abort() and you get a core dump and you can debug easily at the point of the throw instead of the point of the catch.
@ABaumstumpf
@ABaumstumpf Ай бұрын
I like to still catch those things (but rarely have things worth catching) cause along the way it can provide some additional information about what the program was about to do and which information is relevant. And coredumps can be a royal pain: Ever had a program crash due to std::regex? Yeah thousands of stackframes -.-
@gutoguto0873
@gutoguto0873 4 ай бұрын
Great talk 😊
@fareloz
@fareloz 28 күн бұрын
Why std::string& what() getter is not noexcept?
@binary132
@binary132 4 ай бұрын
Ok, I’m going to take exception (pun intended) to the exceptional-variant visitor - that’s what polymorphic exception handlers are for, isn’t it?
@thelatestartosrs
@thelatestartosrs 4 ай бұрын
My only problem with std::expected, having used it recently, is that you can't automatically compose `errors...`, I really wish we could declare functions like `std::expected find(const T& collection, auto&& predicate) { ... return std::unexpected { SomeErrorNotPresentInTheSignature{...} };` This is the consequence of implementing stuff like expected, optional, variant at the library level and not the language level. Also, I do think it sucks that std::expected is defined as std::expected and not std::expected which would encapsulate the variant.
@GreenJalapenjo
@GreenJalapenjo 2 ай бұрын
Hmm that could only work for functions defined in the same translation unit though, just like function templates.
@abit_gray
@abit_gray 3 ай бұрын
My approach to exceptions is simple - Turn on debugger breaking when an exception is thrown. It you need to click it so much that it is annoying (which to some people can be just one exception), you should refactor the code to not hit that exception. Sometimes it is OK to have an exception but not always. I know a lot of companies do not like exceptions as just use return value as an error code but I consider that to be only valid before C++11 ("Modern C++").
@gtdcoder
@gtdcoder 4 ай бұрын
29:03 This is still not sufficient. If connect(…) throws, notify will never be called. This try_connection function is not really an example of bad exception usage. It is an example of lack of cohesion. It should not decide when to call notify. It should just try calling connect a max number of times and provide the type of any error that occurs. There are 3 errors it should handle: Too many retries, connect returns false, and connect throws an exception. The exception can be caught within the function or allowed to propagate if documented sufficiently that the function might throw it.
@PaulMetalhero
@PaulMetalhero 4 ай бұрын
Is there any way to catch an OmegaException ?
@xmk89
@xmk89 4 ай бұрын
Inherit it from some class, catch by the base
@emiliancioca
@emiliancioca 4 ай бұрын
Maybe a common empty base class
@arisweedler4703
@arisweedler4703 4 ай бұрын
Yes, you can catch any OmegaException templates on T by catching the base class that each template derived from, which is std::expected.
@AlfredoCorrea
@AlfredoCorrea 4 ай бұрын
that is the catch (no pun intended) of this design, you can’t catch an arbitrary T (as a template). You have to either 0) use the template to generate named types (as described) or 1) create a concrete variant with all the possibilities (as described), you have to name it, otherwise you can get the order of variants wrong, or 2) create an inheritance relation between specializations of Omega, or 3) isolate common functionality of Omega in OmegaBase. Most of this options really defeat the purpose IMO.
@haxpor
@haxpor 4 ай бұрын
Thank you for the talk. Good notes about RTTI, and polymorphic-related. Anyhow sadly, first portion of the talk is too dry and too much on theorical in which speaker pre-warn it won't be.
@TheArech
@TheArech 4 ай бұрын
It started good, but there are few important.. borderline mistakes imo: 1. Some coding guidelines, such as AUTOSAR C++14 for safety critical automotive software (don't be misguided by v14 - it was superceeded by the next C++17 safety guidance by MISRA just a few weeks ago), mandates that each exception thrown has to be different in a noncofusable way. It could be an exception object data payload, but just having a different exception types is perfectly valid solution. 2. When action to take on an exception severely differences from other exceptions - having a separate exception type is a perfect way to go, since the handler could have a clear path for this specific exception only. 3. std::cout and std::cerr does NOT guarantee to never throw. They could even be redefined and/or use custom operator
@germanassasin1046
@germanassasin1046 4 ай бұрын
57:05. Missed opportunity to call stacktrace function when()
@AlfredoCorrea
@AlfredoCorrea 4 ай бұрын
I think getting stacktrace should be called .how() (.when() could be used for a time stamp, which there is no reason not to have if we are going to bloat our exceptions anyways, as suggested here.)
@binary132
@binary132 4 ай бұрын
My exception class has a “who()” 😇
@alanwest6949
@alanwest6949 4 ай бұрын
I was blind to the controversy around exceptions, I erroneously optimised it away as those who don’t like change and simply prefer status codes. I erroneously assumed those who designed the exception implementation, would want them to work as optimum as all other features. Who wants a language feature implemented slowly, which uses more energy than necessary? I love throwing exceptions to be caught by a handler which understands the context. For freestanding and real-time, I expect to choose when to perform cleanup. What was the benefit in allowing dynamically allocated exceptions? I’m seeing more (C++:-) areas to improve on and better designs. I’m preferring to write my own standard library. Is a language’s standard library more about having a playful class library for university courses? To set everyone on an initial journey for success sooner than later? Is there money in re-implementing C++ exceptions like it’s got to be the fastest, closest to zero cost possible? For all the contexts possible in AI robots, or are we going to use poor exception implementation as the vector to having the upper hand on AI robots? Destroy? Don’t you mean deconstruct?
@theo-dr2dz
@theo-dr2dz 3 ай бұрын
You have to see this in historical context. 1- exceptions are a very old feature. At that time there were no templates yet. No optional, no expected, no variant. The alternative was the C way: checking a return value after all kinds of function calls or some wacky errno mechanism. At that time, cpu's were slow. Memory was fast. Stack space was very limited. So heap allocation was never the bottleneck. People heap-allocated everything, because if you didn't, a moderately deep call stack with some data per layer in it, caused a very real risk of stack overflow. I lived these times. At that time, all those things that he marked as "expensive", would be marked as "cheap". Hardware has changed. A lot. And it was a big improvement over the C way of doing error checking. Believe me, having a check on return code on everything gets old very fast. 2- as Bjarne said at the end, this was the absolute heyday of OOP. OOP was the new craze that would solve all problems in software development. And as such, everything was polymorphic, everything was in inheritance trees, preferably deep ones, so you could really leverage it. Of course, opinions on that have evolved since then. But look at some typical corporate java code and it is all there: massive hierarchies of exception classes, exceptions being used for sanity checking function arguments, exceptions being used for x not found, exceptions being used for flow control, many catch blocks doing the same thing on different exception types. Or just an empty catch of throwable that just swallows everything. It's also a cultural thing that reflects the time it was developed in. These people were not stupid. They lived in a different time when things were different. But that Doug McIlroy guy was really clever.
@Voltra_
@Voltra_ 4 ай бұрын
You "need" exception swallowers if you want your code to be more complicated to maintain and debug. It's like using explicitly exhaustive pattern matching VS adding a default clause where it makes no sense to use one
@binary132
@binary132 4 ай бұрын
I use it to discover exceptions I didn’t know my code could throw, and then I add a handler specific to that type when I discover it. The problem is that unlike variants / pattern matching, you never know what a particular function might possibly throw. That is what I personally find the worst about exceptions.
@RedOrav
@RedOrav 4 ай бұрын
Peter hunts exceptions, his brother hunts dinosaurs
@Kalumbatsch
@Kalumbatsch 4 ай бұрын
*used to
@RedOrav
@RedOrav 4 ай бұрын
@@Kalumbatsch Clever girl
@niklkelbon3662
@niklkelbon3662 4 ай бұрын
38:30 you half of code just dissapear to show us how C++23 is rly 'better' and this ugly 'or_else' interface for optional is rly required (no)
@Sychonut
@Sychonut 4 ай бұрын
Mental masturbation. A bunch of people with not much better to do. I once loved the language and hate my pessimistic outlook on C++ but it's really hard to be optimistic when you have a bunch of ego vultures hell bent on churning out useless features every three years to prove to each other that theirs is bigger.
@rinket7779
@rinket7779 4 ай бұрын
Anyone else find this a very simplistic talk, saying very obvious things, but the guy is sauntering around like he's some kind of genius?
@chrissherlock1748
@chrissherlock1748 4 ай бұрын
What seems obvious to you is not necessarily obvious to others.
@binary132
@binary132 4 ай бұрын
I thought it was pretty amusing and not bothersome. I think there are a lot of people out there who don’t think very carefully about their code and could use a bit of scolding / instruction.
@GregWhiteley
@GregWhiteley 4 ай бұрын
He's not sauntering, he's just Irish 😊. I'm here as someone who's always worked in -fnoexcept workplaces. We use tl:: expected and I'm always concerned we're shooting ourselves in the foot not using exceptions sometimes simply because that's what embedded people do. It's good to check in with how people are using them and ensuring we're still drawing the right lines.
@aDifferentJT
@aDifferentJT 4 ай бұрын
There is little technical in this talk that I would expect to surprise even a moderately experienced programmer. However, that is not the point of this talk, the point is about how we approach exceptions, and that is clearly not simple, otherwise practice wouldn’t vary so wildly across the C++ world. As for your assertion that he is sauntering as if he thinks he is a genius, I think that is probably a cultural difference between you and him, I didn’t think that.
@m3mb3rsh1p
@m3mb3rsh1p 4 ай бұрын
I actually liked his casual mannerisms because it projected a sense that error handling is "not that hard/special." Exceptions and explicit error handling are usually presented as very-serious, this-is-the-way, do-or-die tasks whose absence indicates old paradigms and whose presence is considered to be ideal. I think he did a great job of tempering these perspectives with great examples of simple refactoring, and creative use of standard features that I never would have considered.
@TheNovakon
@TheNovakon 4 ай бұрын
OmegaException is "OmegaLul" omega bad class. I don't endorse it.
@philipbotha6718
@philipbotha6718 4 ай бұрын
Would be useful if you added some justification for your dislike of it.
@ABaumstumpf
@ABaumstumpf Ай бұрын
@@philipbotha6718 That is easy: It is a template. Try catching that. Notice how for every one of his slides he has to introduce a new alias to only handle 1 specific variant.
@marcuszetterquist5923
@marcuszetterquist5923 3 ай бұрын
Please watch some other presentation about exceptions - there is a bunch of things wrong or muddy in this one. Makes me sad. Ex: - bad_alloc exists for a good reason, if you just wish it away you are working in a dumbed down subset of C++, just like those people wishing away error handling and exceptions together - Logging strings is not the core reason you catch exception. Do not destroy typed facts by turning them to unparsable text - The function throwing an exception mustn’t assume that no clients will ever need to differ between types of exceptions - Omega exception basically throws a non-parsable string. Don’t use it Use Perl if you want strings instead of type-safety. Look at how std uses exceptions and do the same.
@ABaumstumpf
@ABaumstumpf Ай бұрын
Everything but NOT "Look at how std uses exceptions and do the same.".
@ElMagic64
@ElMagic64 4 ай бұрын
exceptions are such a bad idea, just handle the errors lol
@philipbotha6718
@philipbotha6718 4 ай бұрын
First thing most people do is to ignore return codes. Lucky if they at least check for success. Writing proper error handling code is often significantly harder than what the code is supposed to do when there aren't errors.
@cranil
@cranil 4 ай бұрын
​@@philipbotha6718 People also mostly ignore exceptions by "handling" them so the point is moot.
@videofountain
@videofountain 2 ай бұрын
Slide 73 and So Forth. Derivation List of Lambda. kzbin.info/www/bejne/haqQh4enr5aSa5osi=LgeuBVB1SmPmgiR0&t=2726
Маленькая и средняя фанта
00:56
Multi DO Smile Russian
Рет қаралды 2,4 МЛН
Can You Draw The PERFECT Circle?
00:57
Stokes Twins
Рет қаралды 50 МЛН
The World's Fastest Cleaners
00:35
MrBeast
Рет қаралды 131 МЛН
Diagramming: The Ultimate Learning Tool
3:57
MAX DEPTH
Рет қаралды 4
For a fistful of idioms - Ivan Čukić
1:03:02
cppzurich
Рет қаралды 157
Thinking Functionally in C++ - Brian Ruth - CppCon 2023
50:25
phone charge game #viral #tranding #new #reels
0:18
YODHA GAMING RAAS
Рет қаралды 12 МЛН
Вы поможете украсть ваш iPhone
0:56
Romancev768
Рет қаралды 456 М.
How Neuralink Works 🧠
0:28
Zack D. Films
Рет қаралды 27 МЛН
САМЫЙ дешевый ПК с OZON на RTX 4070
16:16
Мой Компьютер
Рет қаралды 113 М.