5 ms·
I'd love your opinion on the abundance of "undefined behaviour" (as opposed to implementation-defined, or some new incantation such as "unknown result in variab
by rbultje 6y ago
I'd love your opinion on the abundance of "undefined behaviour" (as opposed to implementation-defined, or some new incantation such as "unknown result in variable but system is safe") for relatively trivial things such as signed (but not unsigned) integer overflows. I've heard that this is to allow for non-twos-complement implementations. However, in practice, you notice that most people use ugly workarounds which lead to ugly code that (because of e.g. casting to unsigned and allowing the same overflow to happen anyway) only work correctly on twos-complement anyway. Is this intended to be addressed in the future in some way?
- stephencanon 6y ago> (because of e.g. casting to unsigned and allowing the same overflow to happen anyway) only work correctly on twos-complement anyway Unsigned arithmetic never overflows, and guarantees two's-complement behavior, because unsigned arithmetic is always carried out modulo 2^n: > A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. (6.2.5, Types) Doing the computation in unsigned always does the "right thing"; the thing that one needs to be careful of with this approach is the conversion of the final result back to the desired signed type (which is very easy to get subtly wrong).
- shawnz 6y agoWrapping around the modulus to me is an "overflow", although maybe the spec doesn't use the word that way
- GuB-42 6y agoThere is also a difference in x86 assembly, and probably others. For unsigned operations the carry flag is used, and for signed operations, the overflow flag is used.
- kwillets 6y agoMost compilers will translate unsigned (x + y < x) to CF usage.
- _kst_ 6y agoRight, there are (at least) two ways to describe this. One is that unsigned arithmetic can overflow, and the behavior on overflow is defined to wrap around. Another is to say that unsigned arithmetic cannot overflow because the result wraps around. Both correctly describe the way it works; they just use the word "overflow" in different ways. The C standard chooses the second way of describing it.
- rini17 6y agoAnd are there standard primitives to do this correctly (signed-unsigned-signed conversion) that never invoke undefined behavior?
- stephencanon 6y agoSigned to unsigned conversion is fully defined (and does the two's complement thing): > Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type (6.3.1.3 Signed and unsigned integers) Unsigned to signed is the hard direction. If the result would be positive (i.e. in range for the signed type), then it just works, but if it would be negative, the result is implementation-defined (but note: not undefined). You can further work around this with various constructs that are ugly and verbose, but fully defined and compilers are able to optimize away. For example, `x <= INT_MAX ? (int)x : (int)(x + INT_MIN) + INT_MIN` works if int has a twos-complement representation (finally guaranteed in C2x, and already guaranteed well before then for the intN_t types), and is optimized away entirely by most compilers.
- jimktrains2 6y agoInteresting. I guess most/many arch's overflow flag is set when the sign bit changes and the carry flag when the result rollsover the word size. I think most people colloquially call going A + 1 = B where B < A an overflow. Interesting. I knew they're different things, but never really thought about my word choice.
- _kst_ 6y agoA quibble on wording: Unsigned overflow is not "twos-complement". It gives you the same bit patterns that typical two's-complement overflow gives you, but strictly speaking two's-complement is a representation for signed values.