7 points birdculture 1 hour ago 4 comments

Hizonner 12 minutes ago | parent

The compiler is allowed to transform your code if it can prove that the result would interact with the outside world in exactly the same way as your original code would, right? You can optimize on "I already checked the value of X" if you can prove that nothing could have changed X.

Well, it sounds like a lot of compilers are making unjustified assumptions about what the outside world is allowed to affect or observe. Maybe with the encouragement of specs, maybe not.

wat10000 7 minutes ago | parent

Sort of. Its idea of “the outside world” is very restrictive. Simple example: write into a pointer, then free it. From the compiler’s perspective, this write can’t be observed and can be removed. It’s not legal to read memory after it’s been freed, so there’s no legal side effect from that write. But in reality, we can use a dangling pointer or a debugger and read bat memory just fine.

kelnos 7 minutes ago | parent

I don't think that's the problem, and I think your "if it can prove..." isn't really accurate.

The compile can transform your code if the result of the computations it makes is the same (plus any ordering guarantees you've encoded with the correct primitives, etc.). "Interact with the outside world in exactly the same way" is way too strong a guarantee.

The canonical example is the constant-time comparison. You want to compare a provided password hash with the one in your database in such a way that every comparison, regardless of success or failure, completes in exactly the same amount of time. The compiler does not care about this desire of yours, though, and can and will try to optimize things so it will stop the comparison as soon as it knows they don't match, which can take different amounts of time depending on the input. This is perfectly valid and reasonable, but breaks security sometimes.

Another example is to allocate some memory, write to it, and free it, without reading it. The compiler is free to optimize the entire thing away. We have `volatile` in C because sometimes merely writing to a memory address has side-effects that aren't visible to the compiler, but if you don't use it, the compiler can do what it wants.

fithisux 9 minutes ago | parent

Compiler does what I tell it. Not the other way around.