top | item 40450196

(no title)

rperez333 | 1 year ago

I know nothing about Zig, but this is pretty interesting and looks well designed. Linus was recently very mad when someone suggested a new semantics for overflow:

—— I'm still entirely unconvinced.

The thing is, wrap-around is not only well-defined, it's common, and EXPECTED.

Example:

   static inline u32 __hash_32_generic(u32 val)
   {
        return val * GOLDEN_RATIO_32;
   }
and dammit, I absolutely DO NOT THINK we should annotate this as some kind of "special multiply". —-

Full thread: https://lore.kernel.org/lkml/CAHk-=wi5YPwWA8f5RAf_Hi8iL0NhGJ...

discuss

order

jcranmer|1 year ago

> The thing is, wrap-around is not only well-defined, it's common, and EXPECTED.

No, it's really not. Do this experiment: for the next ten thousand lines of code you right, every time you do an integer arithmetic operation, ask yourself if the code would be correct if it wrapped around. I would be shocked if the answer was "yes" in as much as 1% of the time.

(The most recent arithmetic expression I wrote was summing up statistics counters. Wraparound is most definitely not correct in that scenario! Actually, I suspect saturation behavior would be more often correct than wraparound behavior.)

This is a case where I think Linus is 100% wrong. Integer overflow is frequently a problem, and demanding the compiler only check for it in cases where it's wrong amounts to demanding the compiler read the programmer's mind (which goes about as well as you'd expect). Taint tracking is also not a viable solution, as anyone who has implemented taint tracking for overflow checks is well aware.

cozzyd|1 year ago

It depends heavily on context.

For the kernel, which deals with a lot of device drivers, ring buffers, and hashes, wraparound is often what you want. The same is likely to be true for things like microcontroller firmware and such.

In data analysis or monte carlo simulations, it's very rarely what you want, indeed.

samatman|1 year ago

I think it's critical that we do annotate it as a special multiply.

If wraparound is ok for that particular multiplication, tell the compiler that. As a sibling comment says, this is seldom the case, but it does happen, in particular, expecting byte addition or multiplication to wrap around can be useful.

The actual expectation of the vast majority of arithmetic in a computer program is that the result will be correct in the ordinary schoolyard sense. While developing that program, it should absolutely panic if that isn't the case. "Well defined" doesn't mean correct.

I don't understand your objection to spelling that `val *% GOLDEN_RATIO_32` is. When someone sees that (especially you, later, coming back to your own code) it clearly indicates that wrapping is expected, or at least allowed. That's good.

bregma|1 year ago

Unsigned integer overflow is not undefined in C or C++. You can rely on how it works.

Signed integer overflow, on the other hand, is undefined. The compiler is allowd to assume it never happens and can re-arrange or eliminate code as it sees fit under that assumption.

How many lines will this code print?

    for (int i = INT_MAX-1; i < 0; ++i) printf("I'm in danger!\n");