I have read here that compiler is free to remove call to memset
if it knows that passed memory buffer is never used again. How is that possible? It seems to me
"compiler has no right to assume that whatever happens inside it, will have no side effects."
That's correct. But if the compiler in fact knows what actually happens inside it and can determine that it really has no side effects, then no assumption is needed.
This is how almost all compiler optimizations work. The code says "X". The compiler determines that if "Y" is true, then it can replace code "X" with code "Z" and there will be no detectable difference. It determines "Y" is true, and then it replaces "X" with "Z".
For example:
void func()
{
int j = 2;
foo();
if (j == 2) bar();
else baz();
}
The compiler can optimize this to foo(); bar();
. The compiler can see that foo
cannot legally modify the value of j
. If foo()
somehow magically figures out where j
is on the stack and modifies it, then the optimization will change the behavior of the code, but that's the programmer's fault for using "magic".
void func()
{
int j = 2;
foo(&j);
if (j == 2) bar();
else baz();
}
Now it can't because foo
can legally modify the value of j
without any magic. (Assuming the compiler can't look inside foo
, which in some cases it can.)
If you do "magic", then the compiler can make optimizations that break your code. Stick to the rules and don't use magic.
In the example you linked to, the code relies on the compiler bothering to put a particular value in a variable that is never accessed and immediately ceases to exist. The compiler is not required to do anything that has no effect on the operation of your code.
The only way that could effect the code is if it peeked at unallocated portions of the stack or relied on new allocations on the stack having values they previously had. Requiring the compiler to do that would make a huge number of optimizations impossible, including replacing local variables with registers.