Remix.run Logo
jmgao 11 hours ago

There are some even funnier cases like this one: https://gcc.godbolt.org/z/cbscGf8ss

The compiler sees that foo can only be assigned in one place (that isn't called locally, but could called from other object files linked into the program) and its address never escapes. Since dereferencing a null pointer is UB, it can legally assume that `*foo` is always 42 and optimizes out the variable entirely.

publicdebates 11 hours ago | parent [-]

To those who are just as confused as me:

Compilers can do whatever they want when they see UB, and accessing an unassigned and unassiganble (file-local) variable is UB, therefore the compiler can just decide that *foo is in fact always 42, or never 42, or sometimes 42, and all would be just as valid options for the compiler.

(I know I'm just restating the parent comment, but I had to think it through several times before understanding it myself, even after reading that.)

jmgao 9 hours ago | parent | next [-]

> Compilers can do whatever they want when they see UB, and accessing an unassigned and unassiganble (file-local) variable is UB, therefore the compiler can just decide that *foo is in fact always 42, or never 42, or sometimes 42, and all would be just as valid options for the compiler.

That's not exactly correct. It's not that the compiler sees that there's UB and decides to do something arbitrary: it's that it sees that there's exactly one way for UB to not be triggered and so it's assuming that that's happening.

masklinn 10 hours ago | parent | prev [-]

Although it should be noted that that’s not how compilers “reason”.

The way they work things out is to assume no UB happens (because otherwise your program is invalid and you would not request compiling an invalid program would you) then work from there.

actionfromafar 6 hours ago | parent [-]

No who would write an incorrect program! :-d