3 ms·
>> One major change in the language is that two’s complement is now mandatory as a representation for signed types. This pleases me greatly. Two's complement w
by phkahler 4y ago
>> One major change in the language is that two’s complement is now mandatory as a representation for signed types.
This pleases me greatly. Two's complement won decades ago. This also means they could define integer overflow as 2's complement rollover, which is almost universal but is still considered undefined behavior.
- layer8 4y agoIt might remove too many compiler optimization opportunities (see e.g. http://kristerw.blogspot.com/2016/02/how-undefined-signed-overflow-enables.html http://kristerw.blogspot.com/2016/02/how-undefined-signed-ov...) for the standard to disallow them now.
- ElevenLathe 4y agoMeaning there are too many compilers currently producing fast-but-probably-not-what-the-programmer-meant code that will need to be changed produce slower-but-probably-what-the-programmer-meant code? Or do I misunderstand? Seems like a win to me if so.
- pwdisswordfish9 4y agoSlower-and-probably-not-what-the-programmer-meant-either code.
- kllrnohj 4y agoNo, you misunderstand. Wide contacts are not universally superior to narrow ones, and more often than not narrow contacts catch more bugs than wide ones do. For example almost never does a programmer want int to rollover in a for loop. Defining that behavior doesn't help, and indeed makes tools like linters or sanitizers less useful.
- dzaima 4y agoIf you do "for (int i = 0; i < len; i++) data[i] = 0;" and len happens to be above 2^31, is your intent to write 2 billion zeroes, and then write 2 billion zeroes behind the data pointer, and repeatedly do that forever (never mind other UB that that results in)? Probably not. While two's complement signed rollover can be pretty useful, in 99% of cases you don't need it, and casting to unsigned for the 1% is a worthwhile sacrifice for the better optimizations for the common case, and it'll be pretty clear when you want wrapping or not (and sanitizers will be able to keep reporting signed overflow as errors without false positives).
- a1369209993 4y agoNo, my 'intent' is to get: error: signed integer variable used as array index (-Wsigned-index) `int i`: should be `size_t i` error: comparison of signed to unsigned integer (-Wsigned-comparison) `i < len`: `i` has type `int`; `len` has type `size_t` Scare quotes on "intent", because I don't write (that particular kind of) obviously broken code in the first place, but the upshot is that i and len both need to be size_t, and anything that lets the compiler obscure that is de facto bad. Edit: previously assumed len was wrong too, but on rereading, you were implying len was already the correct type, and only i was wrong. (Also, the word "variable" is significant; IIRC something like 5+bytecode_next_char promotes to int, but can't actually be negative[1] so shouldn't generate a warning.) 1: Assuming the compiler is configured correctly, ie char is unsigned.
- dzaima 4y agoThe compiler could do those things too (-Wsign-compare is a thing; nothing for signed index though), but that won't change the existing code that uses "for (int ..." (incl. 637K C source files on github), and those warnings could be false positives too (e.g. signed indexes into lookup tables, or keeping using an int32_t after having asserted somewhere before (possibly out of the compiler's vision) that it's non-negative).
- phkahler 4y agoSo GCC is defining one behavior for overflow in the optimizer (assuming there is no overflow so algebraic expressions can be optimized) and generating code that behaves differently (a+b will wrap around for signed and unsigned types) That seems suspect to me but I understand why they'd do it.
- zajio1am 4y ago> This also means they could define integer overflow as 2's complement rollover, which is almost universal but is still considered undefined behavior. No, they should not. Integer overflow is in most cases logic error, like division by zero or NULL pointer dereference, so it should stay undefined.
- pantry-man 4y agoIt can still be well defined behaviour and still an error
- marssaxman 4y agoThat's only true for the relatively recent and generally unhelpful "nasal demons" interpretation of undefined behavior; under the older concept, which is more like "do whatever the sensible thing would be on the target platform", rollover is probably just what you want.
- zajio1am 4y agoDistinction between undefined, unspecified, and implementation-defined is already in ISO C99 specification and is rather specific: "NOTE: Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (...), to terminating a translation or execution (...)." > which is more like "do whatever the sensible thing would be on the target platform" That is a meaning of 'implementation-defined' in C parlance.
- marssaxman 4y agoI am familiar with the verbiage in the specification. My contention is that the currently popular tendency for C compilers to generate code which behaves in ways that are absurd and unpredictable, on the grounds that you shouldn't have been doing that anyway, is an unhelpful indulgence on the part of the compiler engineers.