4 ms·
well, alternative compilers can excel in not providing broken optimizations based on UB. -Oboring is a thing in the kernel. chibicc e.g
by rurban 5y ago
well, alternative compilers can excel in not providing broken optimizations based on UB. -Oboring is a thing in the kernel. chibicc e.g
- ChuckMcM 5y agoI have often wondered if a C89 standard with no UB would be the definitive go to language for systems. I mean you COULD define things if you chose to, right?
- MaxBarraclough 5y agoSome kinds of UB can easily be handled that way. GCC offers a flag to guarantee wrapping on signed arithmetic overflow, for instance. [0] It wouldn't be easy to nicely handle every instance of UB though. The current state-of-the-art for that kind of thing would be something like Valgrind, an extremely 'intrusive' runtime system. This is because of the particulars of the C language. For instance, the way it handles arrays and pointer arithmetic make it difficult to detect every instance of out-of-bounds access. [0] -fwrapv, see https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
- ChuckMcM 5y agoI think we're talking about different things, but maybe not. Using out of bounds references in arrays and pointer arithmetic are unsafe but they can be defined. The definition of "array accesses using indexes that are outside the range of 0 - the declared array size will access memory in the data segment. The compiler will treat that access as if the addressed memory had the type specified for the array." The behavior is defined, it is unsafe, but it is defined. Not like "the compiler may or may not choose to optimize out loads and stores, or re-order them." which especially on embedded systems creates bugs where the things like "read the status register THEN read the data register (which clears the status register when read)" those get re-ordered and suddenly your loop never exits because your status bit is never set. That kind of UB needs to die in a fire IMHO.
- pjmlp 5y agoOut of bounds is only defined for length + 1, for anything else anything goes.
- MaxBarraclough 5y agoThat doesn't sound right. C (and C++) permit you to do pointer arithmetic to derive a pointer value pointing to one element beyond the final element of an array. This special treatment doesn't extend to dereferencing though - if you deference that pointer, that's UB. If you do pointer arithmetic to derive a pointer value pointing 2 or more elements beyond the final element of an array, that's undefined behaviour, even if you never dereference that pointer.
- pjmlp 5y agoSure, I just didn't want to spend too much time explaining all details, my failure.
- tialaramex 5y agoIt's downright perverse to insist that you should be able to assume all accesses are volatile reads/ stores just because that was momentarily convenient. C lacks the intrinsics you'd actually want for this (explicit load/ store of various machine sizes) but it does provide the "volatile" storage qualifier which is what you should be using to do what you apparently wanted in C today. It makes no sense to demand everybody else writes some sort of "not-volatile" qualifier in front of every variable to tell the compiler that actually this is just a variable and it's OK to optimise.
- Thiez 5y ago> which especially on embedded systems creates bugs where the things like "read the status register THEN read the data register (which clears the status register when read)" those get re-ordered and suddenly your loop never exits because your status bit is never set. Why are the embedded systems programmers not using `volatile`, which exists for this exact reason?
- Ar-Curunir 5y agoHow do you eliminate ub without memory safety?!
- isomel 5y agoFor example, as mentioned in another comment, by making all read and write `volatile`, that way, dangling pointer and out of bounds are "defined" to be memory corruption or crash, and not the compiler optimizing the code in a way that the programmer did not enticipate.
- znpy 5y agoWouldn't that bring a performance penalty though?
- __d 5y agoYes. But the current trade-off (performance always wins) means that kernels and other embedded-style programs cannot rely on the compiler doing the "reasonable" thing for UB because it's explicitly allowed to do whatever it wants (which is generally, try for better performance). For kernel-style work, slightly lower performance but predictable/defined behavior for some of what is currently UB, makes life much simpler.
- Ar-Curunir 5y agoYou don’t need to do what youre saying for that; Rust provides a way to get both performance and safety