|
|
|
|
|
by yorwba
3291 days ago
|
|
The compiler is not doing "whatever the hell it wants". It chooses an interpretation of the undefined behavior and then optimizes based on that. Of course, if the programmer had something else in mind, they will be surprised about the result; but it's their fault for not being precise enough. So why make reads of uninitialized values undefined at all? Consider code like this: uint64_t x; // Will be initialized later
/* ... */
if(check_some_condition(y, z)) x = (uint8_t) f(b,d);
/* ... */
if(check_some_other_condition(foo)) x = (uint8_t) bar;
/* ... */
x &= 0xf;
/* ... */
if(x & 0x800) do_stuff();
Now the compiler has no way of knowing whether x will be initialized or not. But if it has been initialized, then it's value must be in 0..255, so the & 0xf can be limited to the lowest byte. But this means that the test for x & 0x800 will always be false, and stuff will never be done, so the compiler can optimize it out, reducing code size and thus cache pressure.If these assumptions don't hold, then some later code may get passed a value for x that has the bit in 0x800 set, and expect do_stuff() to have initialized some data structure, which didn't happen, and the code blows up. But the compiler was just working from what it knew, and under the assumption that the programmer wouldn't depend on completely arbitrary values that happened to be in memory, everything it did was perfectly sensible. |
|
Why should it do that? Just stop compiling and yell at the user, demanding proper code. I'd not let the code you gave as an example pass any review because it is not clear what the author intended.