Live data from Hacker News

Current hardware trends make C++ exceptions harder to justify

open-std.org

391–400 of 516 posts

Re: Current hardware trends make C++ exceptions harder to justify

#391
post #283

Earlier quoted context omitted.

It is in Go Lang which shares error handling philosophy with GP.

Go panics do not simply abort. "For a real-world example of panic and recover, see the json package from the Go standard library. It encodes an interface with a set of recursive functions. If an error occurs when traversing the value, panic is called to unwind the stack to the top-level function call, which recovers from the panic and returns an appropriate error value (see the ‘error’ and ‘marshal’ methods of the en…

But philosophically, they should just abort.

Re: Current hardware trends make C++ exceptions harder to justify

#392
post #288

Earlier quoted context omitted.

The reason they care called "exceptions" is they are not part of the normal behavior of the function (/block, algorithm) and aren't something that can be handled locally. Something that is exceptional is unusual, out of the typical scope of things. In English there is a phrase, "the exception to the rule" -- because the rule is what normally happens. So if you are trying to hold a lock you don't throw an exception, y…

English also has the phrase "the exception proves the rule" - and it's just swell when our general code handles special cases. I would have not have thought an unreachable host was exceptional, given that it's quite normal.

In this aphorism, “prove” has an archaic meaning: “tests the rule”.

The point is that handling the host unreachable is almost always semantically higher level than the code opening the connection. This the code opening doesn’t implement the policy of what to do when the situation occurs. In the case, say, of a hard-coded address then it’s possible the author of that piece of code does know how to handle a host unreachable case.

Re: Current hardware trends make C++ exceptions harder to justify

#393

Earlier quoted context omitted.

The "exceptions should be exceptional aka rare" line sounds aspirational, but I wonder how true it is if you survey the general landscape of actual libraries.

On top of that, you never know the context in which your users will call your library. Are you encoding a single file on a local machine? Or 1000 files on some HPC 128-core machine? Do we really want to be in a world where all libraries need to be written with and without exceptions since we can't know the context they'll be used in?

Why is the error occurring in the first place? In my opinion, exceptions/errors should be rare. If it's a software problem, it should eventually be fixed. If it's an infrastructure problem, it should be fixed. It's not just something that should continue to happen without any mitigation what so ever over time.

Re: Current hardware trends make C++ exceptions harder to justify

#394

Earlier quoted context omitted.

> I want functions to have a side channel to the user/operator that is not necessarily in the main flow path. That is the essence of the Common Lisp condition system, and you can get there in most languages with closures, or at least function pointers, and exceptions or some other non-local return mechanism using a combination of callback functions for the conditions and unchecked exceptions for the default, unhandle…

I'm not sure callbacks alone can be equivalent to a resumable conditions system. You really need full coroutines in the general case. Anyway, what you are proposing is more of a partial alternative to exceptions, since the caller has to be aware of what's 'handled' in advance, whereas conditions may additionally unwind up to a predefined restart point or fail up to the caller similar to a non-handled exception.

> I'm not sure callbacks alone can be equivalent to a resumable conditions system.

I agree, but I was not relying solely on callbacks. You do need some form of non-local return (such as exceptions or continuations) to implement the "resumable" aspect with a choice of restart points, in addition to the callbacks.

> You really need full coroutines in the general case.

I'm having a hard time imagining an error-handling scenario that would require the full power of coroutines—in particular the ability to jump back into the condition handler after a restart. In any case, most languages (even C, if you work at it) can express coroutines in some form or another.

> Anyway, what you are proposing is more of a partial alternative to exceptions, since the caller has to be aware of what's 'handled' in advance, whereas conditions may additionally unwind up to a predefined restart point or fail up to the caller similar to a non-handled exception.

Clearly there has been a breakdown in communication, as I though this was exactly what I described. The handler callbacks are "ambient environment" (i.e. per-thread variables with dynamically-scoped values) so there is no particular need for the caller to be aware of them unless it wishes to alter the handling of a particular condition. Restart points can be implemented by (ab)using unchecked exceptions for control flow to unwind the stack, or more cleanly via continuations if the language supports them.

Re: Current hardware trends make C++ exceptions harder to justify

#395
post #82
post #44

Begs the question: Why C++? Legacy projects (I am not being pejorative, they are important) which must be maintained aside, should not C++ be deprecated? We have many new languages, we always had C. What does C++ give us in 2022 that makes up for the enormous cognitive load of understanding and keeping up with it.

Little things... Destructors; overloading; namespaces; and yes, exceptions. Things I can no longer live without. Generics (templates) are nice to have, too.

You will learn to live without overloading and exceptions.

Generics is an absolutely must have. In 1997 I was was giving up on C++ when I discovered the standard template library. I was lucky to be using Visual C++ on Microsoft. The (only) good thing good thing about that compiler is it implemented the STL using Stepinov's reference.

Stepanov defined STL in 1994. By 1997 there were SFA implementations that followed the standard. Most "improved" it and made a mess of it, like GCC.

(I may have remembered that wrong, mēh)

It completely changed the way I thought about computer programming. Before that I was always programming in a style suited to assembly programming

Re: Current hardware trends make C++ exceptions harder to justify

#396
post #39

Earlier quoted context omitted.

It has been many years since I used C++ But returning null is an obvious choice. Combined types which return the structure or an error are another. Has the advantage of returning error information, why failure. There are many ways

You can’t return null from a constructor (constructors have no return)

What dumb design.

I thought the constructor returned a pointer to the memory created.

No return? Stupid!

Re: Current hardware trends make C++ exceptions harder to justify

#397
post #191

I find this paper quite unconvincing. Exceptions are exceptional so in principle it doesn't matter (within reason) how long it takes to throw one as long as it costs nothing not to do so. So measuring the cost of repeated throws IMHO doesn't cast light on any useful case, and the approaches that add runtime cost for the path not taken, even Herb Sutter's, are not acceptable. His code transformation example is simply…

The only way exceptions should be exceptional is that they should rarely be used in any code base. At best, the are a micro optimization that helps you a tiny bit in the success case. They should be used when standard return value errors are measured to be impacting perf (ie. exceedingly rarely). Unfortunately, C++ language authors made them basically a requirement for OOP and RAII. Imagine writing a parser. Can you…

This just spectacularly bad advice and policy. Point performance is the worst way to decide about error handling.

The overlap between "things that fail and the caller knows something useful to do", and "things that fail and somebody maybe six levels back in the call chain might know something to do" is remarkably thin. Most things are the latter. Once in a while, it makes sense to provide one for each: (1) open a file, and it had better succeed or you might have to bail out, or (2) see if a file is there.

The reason exception is the default, aside from that there are plenty of ways to return an error report, is that when you need code to clean up, the destructors are right there. They get exercised every time through the code, so are well-tested. How often is your special-snowflake error handler ever exercised? And the next one? And the next one? Even before you have given a moment's thought to error handling, your destructors are cleaning up, correctly. So, even if you haven't written code to handle it, your program has remained in a well-defined state. And, very often, you don't even need to write them: they are auto-generated from things the compiler already knows.

If you have set up a high-level catch block, you get there without fuss, and that code knows something correct to do, even if it is only to shut down cleanly. If you left a record of what was about to be attempted, that code knows what to try next.

Re: Current hardware trends make C++ exceptions harder to justify

#398

Earlier quoted context omitted.

Ok, I'll bite. Disclaimer: I'm not a software engineer, FPGA engineer by training. The use model I have in my mind is that my functions all work 99.999% of the time, but occasionally something happens where basically I want to throw up, I want the whole thing to collapse. Exceptions are great for me. I'm in an industry where "stop" is an okay solution in the rare occasion something goes wrong. So what's the alternati…

> my experience essentially does not involve catching exceptions Which is part of the problem. If you're not catching the exception, you don't need exceptions. You just need a way to log stuff, such as a trace, and exit the program. New languages such as Rust and Go encourage this explicitly - that is, use the ordained error path in the return value for expected errors, and only panic for catastrophic errors (or use…

When you are writing a library, you don't know what the program that calls you might have set up to handle failures, but you know exactly how to get to it: throw, and you are there, and it is now for the caller to decide what to do, thus not your problem. A library that exits has stolen control away from its rightful owner.

Very few languages are as finely tuned to the needs of libraries and users of libraries as C++. Exceptions are an essential part of that compact. Failing to abide by it makes your library a bad citizen.

Re: Current hardware trends make C++ exceptions harder to justify

#399
post #397

Earlier quoted context omitted.

The only way exceptions should be exceptional is that they should rarely be used in any code base. At best, the are a micro optimization that helps you a tiny bit in the success case. They should be used when standard return value errors are measured to be impacting perf (ie. exceedingly rarely). Unfortunately, C++ language authors made them basically a requirement for OOP and RAII. Imagine writing a parser. Can you…

This just spectacularly bad advice and policy. Point performance is the worst way to decide about error handling. The overlap between "things that fail and the caller knows something useful to do", and "things that fail and somebody maybe six levels back in the call chain might know something to do" is remarkably thin. Most things are the latter. Once in a while, it makes sense to provide one for each: (1) open a fil…

> Point performance is the worst way to decide about error handling.

My point is exactly that. It's more important to have a single common way of doing error handling than it is to have a small perf improvement. That's why I recommend return values. You'll never hit a perf problem with them.

Exceptions cannot be used in code hot paths (~thousands of iterations) when it's not a small perf problem anymore. Therefore, they cannot be your only method for signaling failure. And therefore, assuming we care about consistency and composability of code, it's far better to use return value based error handling unless you have good reason (almost never). Ideally with syntatic sugar from the compiler (see Rust, Zig, Swift, etc).

> when you need code to clean up, the destructors are right there.

Exceptions are not needed to achieve this. C++ calls the same 'well tested' destructors when you return from a function.

The one point in your favor, that I acknowledged above, is that C++ requires exceptions to report failure from Constructors and Destructors, for OOP, std::vector initialization, for much of the standard library etc. Thats a travesty.

Re: Current hardware trends make C++ exceptions harder to justify

#400
post #356

Earlier quoted context omitted.

Is "cargo cult" really what you mean here. It doesn't seem to fit.

Yes, the blind following of "patterns" because you think that is what makes for "good code" is a perfect example. Especially when fitting the predefined pattern bends your implementation otherwise out of shape. A design pattern is a way of communication. If you turn it into a procrustean tool you don't even understand why they exist.

Most design patterns are anti-patterns: they represent a failure of the language to offer a way to abstract the pattern into a component or native language construct.

It is usually better if it can be captured in a library. But sometimes, particularly in weak languages, nothing but core language support will do. A fancy core language feature should embarrass the language designer.

Sometimes, a language evolves to the point where a core feature could be as well implemented as a library component. That is a marker of real progress, because now the feature can be offered in a dozen variations in a dozen libraries, each tailored to local conditions, where the core feature had to ruthlessly ignore all but the most generic use cases.

Post reply on HN