With these functions, it could be written as: if (__builtin_mul_overflow(n, m, &n))
It seems the C committee at some point makes things harder than they should. And true, the C committee is not preventing anyone from using something else
(Another reason why we should retire C for most projects)
This seems like entirely the wrong way of looking at it to me. The C committee is not trying to make things harder than they should be, but they’re really just a committee in charge of C. Their goal isn’t to make C into some kind of beautiful safe language, it’s just to provide incremental improvements to C for the benefit of people stuck using it for whatever reason.
Like, the C committee isn’t trying to stop you from retiring C. They’re just trying to help out the people who aren’t retiring C, for whatever reason—which could be toolchain availability (lots of architectures out there, you may only have a C compiler for some), could be so they can work with a legacy codebase, could be that some other tooling or process they have works with C (the various “safe C” / analyzable subsets or formal verification processes).
However, leaving the overflow check/behavior on the multiplication as "implementation defined" seems like a bad call to me
Not everyone cares about the benchmarks, but enough do.
However in 40 years they already made their point not to care beyond make C a portable macro assembler with more UB issues than writing in raw Assembly.
The UB issues are not going away. Some people who use C need to get good performance out of it. If you try fixing the UB issues, you end up having to remove optimization passes from your C compilers. That’s just not viable—hence, UB issues are here to say.
The correct thing for the C committee is to make slow, careful improvements to C for the people who are stuck using it. And the correct choice for most people is to stop using C in favor of safer languages.
If you try to have the committee fix the safety problems with C, you’re going to end up with something which neither fast nor safe. If you are stuck using C and need it to be safe, you can use formal methods. If you don’t have the budget for formal methods, you need safety, and you’re stuck on a system which only has a C toolchain, then the alternative is to use something which compiles to C.
if (n && m > SIZE_MAX / n)I'd rewrite it as `if (n != 0 && m > SIZE_MAX / n)`. Seems legit to me.
Furthermore, optimisation can't bite you if you test the values before you perform the potentially UB operation (and unsigned operations can never overflow anyway, they are always well-defined).
Edit: inverted meaning since check is for error, not for ok case.
p = m n
If that is gonna overflow, p > SIZE_MAX.Then it would be that (by substitution)
m n > SIZE_MAX
so m > SIZE_MAX/n
except if n = 0. In the latter case, m can be as big as it wants--p will always evaluate to 0.And (size_t)-1 is a silly way to write SIZE_MAX (but it saves you a dependency).
Shouldn't the case of wraparound be caught by testing the resulting size as following?
s = n*m;
if (n && s >= n && s >= m) /* no overflow */ ...
Am I the only one that doesn’t think this is “sweet”?
I mean I know what it does and why and how it works, but IMHO a good language should let you express your intention and algorithm in human terms and logic in which there is no -1 value for an unsigned integer type.