3 ms·
(Edit: oops, I haven't read your second line…) [Indeed,] There's more to it than bugs. Undefined behaviour for instance is generally understood by the program
by loup-vaillant 11y ago
(Edit: oops, I haven't read your second line…)
[Indeed,] There's more to it than bugs.
Undefined behaviour for instance is generally understood by the programmer as being runtime driven craziness. Divide by zero for instance will raise a clean error (generally resulting in a clean crash) on most platform.
Popular C compilers such as GCC and LLVM however, have a different understanding, based on the wording of the standard. They are allowed to assume that undefined behaviour simply doesn't happen, and use that assumptions in optimizations such as dead code elimination or alias analysis. With this stuff, a program that would have exhibited undefined behaviour if compiled straightforwardly is allowed to go bananas at any time. This is compile time driven craziness, a rather different beast.
A classic example of this is signed integer overflow. You perform some arithmetic that may overflow, then check for overflow after the fact. Most architectures perform two's complement modulo arithmetic, so it works without problem. Except that in C, this is undefined behaviour. So your compiler is allowed to assume it never happens. Which means your test that `x >= x+1` is going to be "true" all the time. Which means that your error handling branch is dead code. And that could allow nasty stuff such as buffer overflows.
You could say it's the user's fault for relying on undefined behaviour (that is nevertheless well defined on x86 and ARM assembly). But you gotta admit that's not very intuitive. Yes, in some obscure platforms such an overflow could make your CPU jump in a random place. Yes, relying on this is not portable. But C is supposed to be close to the metal. Few C users would expect the compiler to optimize it all away even if it would work on their platform.
On the other hand, things like strict aliasing are explicitly about enabling compiler optimizations.