Good point that checking for overflow of a multiplication beforehand is hard. But I don't think checking after the fact would be much easier. So thus a C modification to remove the undefined behavior probably wouldn't be very useful still.
The thing is that it's necessary, and (x86, not sure about arm) asm tells you via the d register if not the overflow flag. So why doesn't the C standard arguably provide a misuse-resistant way of doing so? Instead every project having to reinvent it and get it wrong if they do the "obvious" (but wrong) thing.
What would the misuse-resistant way be? Would you want the multiplication operator (*) to return 2 values: the number and a bool telling you whether it overflowed?
Yeah, a standard library function that does this would be good. But many people would just use * instead of this function, and so the problem would partially remain.
mul_would_overflow(), mul_wrap(), mul_saturate(), mul_do_whatever_the_hardware_does_just_please_dont_break_my_code_by_assuming_ub. Can't help people who just use * and don't care about overflow without breaking compatibility, but at least the people who do care won't have to reinvent safe arithmetic.
Yeah, I agree with you. But it would be hard due to there being so many integer types. A binary operation needs to consider 3 types: the types of each argument and the type of the result.
In c++ it would be a little simpler due to templates, so the types of the arguments to the function can be derived. But the type of the result can still confuse programmers. Although maybe it's not so bad, because an overflow that happens during multiplication (or other math operations) is undefined-behavior, but an overflow that happens during assignment of the multiplication result to a variable that can't hold it is only implementation-defined behavior, not undefined behavior.
In that case, something like: [...] if (a > INT_MAX - 1) abort(); int b = a + 1; [...]