4 ms·
Mathematics in C is modular arithmetic built as an abstraction on top of fixed-width numbers. One has to keep reminding oneself of this fact. This got etched in
by farhanhubble 7y ago
Mathematics in C is modular arithmetic built as an abstraction on top of fixed-width numbers. One has to keep reminding oneself of this fact. This got etched in my brain after I saw a piece of code that calculated the middle index of an array in a roundabout way
mid = left+ (right-left) /2 instead of
mid = (right +left) / 2
Although even this code can cause overflows, it has served as a reminder to be cautious even with simple addition or increment operations.
For this reason the best C code I have seen, an in-memory database with lots of pointer arithmetic, array indexing and bitwise operations, had its own 'safer arithmetic' implemented using macros.
- fluffything 7y ago> One has to keep reminding oneself of this fact. No, one doesn't need to do this, and no matter how hard you try, ths doesn't work in practice since you only need to slip once to introduce a CVE into your program. What we need is for compilers to start calling `abort` by default on any kind of integer overflow. If you have a piece of C code in which you actually need integers to overflow with some particular semantics (e.g. saturating, modulo 2, etc.), you should actually call some standard library API that's lets you express this in a very explicit way. I need to use such APIs every now and then from Rust, but 99% of the time, integer overflow is an error, not something I explicitly intended to introduce undefined behavior or wrap with modulo 2, and as a consequence, if that happens to execute silently, my programs which are not programmed to handle this case will eat your laundry. The suggestion that "you have to keep overflow in mind all the time" is nuts, because most of the time, you have more important things to keep in mind than whether overflowing a singed integer is going to cause UB or whether overflowing an unsigned one is going to wrap around, and manually insert checks everywhere every time you use integers. That's just a completely unreasonable expectation to have about programmers and human beings in general.
- deleted 7y ago[deleted]
- jimbo1qaz 7y agoDoesn't Rust arithmetic wraparound on release? I read Microsoft's Midori language paniced/abandoned on overflow even in release, and the compiler got quite good at optimizing overflow checks away.
- steveklabnik 7y agoThe rules are slightly more complex than that to allow the behavior to change in the future, but they currently two’s compliment wrapping, yes.
- fluffything 7y agoIf you wrap around you get implementation defined behavior, which can be chosen to either panic!, or wrap-around. In release, the default is wrap-around, but you can set it to panic.
- MaxBarraclough 7y ago> What we need is for compilers to start calling `abort` by default on any kind of integer overflow GCC supports this for C and C++, but it's off by default. I don't know if any distros build with this flag (-ftrapv) enabled. Seems like a good idea. https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.h...