Advertisement

Error handling: To check every little error or confidently skip them?

Started by November 17, 2023 03:24 AM
13 comments, last by taby 1 year, 1 month ago

Thx for the replies!

@frob Yeah I like the [[nodiscard]] too. To me it enforces the importance of the code creator return values, as well as forcing the user to expect better, meaningful return values (or in the end none, if not required after review), hence good, properly handled code. But since return value is already optional by language default (that we have to put nodiscard manually) in the first place it's a debate to some, I've seen it somewhere after that feature arrived.

@a light breeze Great quick step and examples! On the USB example, can you elaborate why in most cases there's no point? Wouldn't there be any data corruption that maybe the user need to know? or is it because we can just cancel it and write it again nonetheless when they attach it again that it doesn't matter? I assume as an end-user, pointless notifications can be annoying too if it can be solved easily later as long as it's known to be harmless.

@taby Yes. The examples I gave were in C, though (including the link), but I'm more than okay to hear any related opinion in any language (and exception model example, if anyone uses it) including modern C++ (if that's what C++ x standard library means). If you have any comment about error handling specifically with modern C++ multithreading, please let me know. 🙂

arly said:
But since return value is already optional by language default (that we have to put nodiscard manually) in the first place it's a debate to some, I've seen it somewhere after that feature arrived.

There are many other approaches. The design around return values for error codes stems from C, which in turn comes directly from the underlying machine design. Go back to the 1970's and 1960's and on many systems return values were the only option.

In modern systems and modern language use there are many additional options for handling errors and communicating them. The common idiom of an out parameter, a reference with a value set by the function on success, is a good one. The idiom of internal state validity flags can be a good fit for some systems. The idiom of exceptions also communicates errors, although they're relatively expensive in C++ regarding stack unwinding and other tasks. Other methods may be a good fit for other designs, there are plenty of options that we have today which weren't around in past ages.

Again for our systems and code reviews, error conditions are strongly enforced. If something can potentially fail eventually it will fail, so you are best handling it somehow. You may address it by looking for a way to retry, or for permissions attempt to get permissions, or output some logging, or propagate the error out to the caller, or even terminate the program, all of it will depend on the details of the error and the context of the condition.

Advertisement

JoeJ said:
Floating point exceptions can be very useful

Agreed, but those are completely different than C++ exceptions. FP and divide by zero integer exceptions are implemented as hardware interrupts at the OS level. I'd liken those more to asserts, e.g. assert( !isnan(x) ) would behave similarly but would have overhead, while FP exceptions are in hardware and can be trapped.

arly said:

@a light breeze Great quick step and examples! On the USB example, can you elaborate why in most cases there's no point? Wouldn't there be any data corruption that maybe the user need to know? or is it because we can just cancel it and write it again nonetheless when they attach it again that it doesn't matter? I assume as an end-user, pointless notifications can be annoying too if it can be solved easily later as long as it's known to be harmless.

Usually printf is used for informational purposes, not for critical data, so it doesn't matter if the data gets lost. Usually printf output goes to the console where you can see if you're getting the output you're expecting or not. Usually when stdout is redirected, it's going to be processed shortly afterwards so the user is going to quickly notice if the data is incomplete. Usually the user knows better than to remove an USB stick while writing to it. Usually. And often printf is used for reporting errors, so if printf fails, then there's no way to report errors.

Obviously that's not always true, which is why printf returns an error code instead of just silently failing. But in 99% of all cases, this error code can be safely ignored.

My bad. Check out https://github.com/sjhalayka/cpp_thread/blob/master/main.cpp​ for an example that uses a mutex. It was standardized in 2011. That's not exactly modern, but it does the trick!

This topic is closed to new replies.

Advertisement