3 ms·
I would argue that was one of the reasons why those languages lost. I distinctly remember arguments for functions working on array of 10. Oh, you want array of
by prerok 1y ago
I would argue that was one of the reasons why those languages lost.
I distinctly remember arguments for functions working on array of 10. Oh, you want array of 12? Copy-paste the function to make it array of 12. What a load of BS.
It took Pascal years to drop that constraint, but by then C had already won.
I never ever wanted the compiler or runtime to check a subrange of ints. Ever. Overflow as program crash would be better, which I do find useful, but arbitrary ranges chosen by programmer? No thanks. To make matters worse, those are checked even by intermediate results.
I realize this is opinioned only on my experience, so I would appreciate a counter example where it is a benefit (and yes, I worked on production code written in Pascal, French variant even, and migrating it to C was hilariously more readable and maintainable).
- pjmlp 1y agoThankfully instead of overflow, C gets you the freedom of UB based optimizations.
- prerok 1y agoFunny :) It still results in overflow and while you are right that it's UB by the standard, it's still pretty certain what will happen on a particular platform with a particular compiler :)
- ummonk 1y agoNo, optimizing compilers don't translate overflow to platform-specific behavior for signed integers - since it's UB they'll freely make arithmetic or logic assumptions that can result in behavior that can't really be humanly predicted without examining the generated machine code.
- uecker 1y agoThey are free to but not required. You can pick a different compiler, or you can configure your compiler to something else, if it provides such options. I always found it surprising that people did not reject clang for aggressively optimizing based on UB, but instead complained about the language while still using clang with -O3.
- ummonk 1y agoProgrammers don’t have much choice, since most compilers don’t really provide an option / optimization level that results in sane behavior for common UB footguns while providing reasonable levels of performance optimization. The one exception I know of is CompCert but it comes with a non-free license. I definitely do think the language committee should have constrained UB more to prevent standards-compliant compilers from generating code that completely breaks the expectations of even experienced programmers. Instead the language committees went the opposite route, removing C89/90 wording from subsequent standards that would have limited what compilers can do for UB.
- uecker 1y agoThe C89/C90 wording change story is a myth. And I am not sure I understand your point about CompCert. The correctness proof of CompCert covers programs that have no UB. And programmers do have some choice and also some voice. But I do not see them pushing for changes a lot.
- pjmlp 1y agoThe choice is going for other languages because they don't believe WG14, or WG21 will ever sort this out, as many are doing nowadays.
- uecker 1y agoThis is my point, programmers apparently fail to understand that they would need to push for changes at the compiler level. The committee is supposed to standardize what exist, it has no real power to change anything against the will of the compiler vendors.
- ummonk 1y agoThe C standard changed its note about "permissible" undefined behavior (in C89/90) to "possible" undefined behavior (from C99 onwards). This is easily verifiable and not a myth. As to CompCert, I'm not sure if they still make guarantees about type punning, but the older paper had said this: "The semantics of Clight is formally defined in big-step operational style. The semantics is deterministic and makes precise a number of behaviors left unspecified or undefined in the ISO C standard, such as the sizes of data types, the results of signed arithmetic operations in case of overflow, and the evaluation order. Other undefined C behaviors are consistently turned into “going wrong” behaviors, such as dereferencing the null pointer or accessing arrays out of bounds. Memory is modeled as a collection of disjoint blocks, each block being accessed through byte offsets; pointer values are pairs of a block identifier and a byte offset. This way, pointer arithmetic is modeled accurately, even in the presence of casts between incompatible pointer types"
- tredre3 1y agoFYI all major C compilers have flags to enforce the usual two's-complement rollover, even if you enable all optimizations. I always enable at least fwrapv, even when I know that the underlying CPU has well defined overflow behavior (gcc knows this so the flag presumably becomes a no-op, but I've never validated that thought). gcc has -fwrapv and -f[no-]strict-overflow, clang copied both, and MSVC has had a plethora of flags over the years (UndefIntOverflow, for example) so your guess is as good as mine which one still works as expected.
- gmadsen 1y agocompile time user config checking?
- naasking 1y ago> I never ever wanted the compiler or runtime to check a subrange of ints. Ever. Requiring values to be positive, requiring an index to fall within the bounds of an array, and requiring values to be non-zero so you never divide by zero are very, very common requirements and a common source of bugs when the assumptions are violated.