Search code examples
c++optimizationvisual-c++compiler-optimization

Why would a C++ compiler only eliminate useless writes if there's no code after those writes?


I'm inspecting Visual C++ 10 optimization capabilities and found a rather curious thing. All code herein is compiled with /O2.

In the following code:

int _tmain(int argc, _TCHAR* argv[])
{
    char buffer[1024] = {};
    MessageBoxA( 0, buffer, buffer, 0 );
    memset( buffer, 0, sizeof( buffer ) );
    return 0;
}

the call to memset() before return is eliminated from the machine code (I inspect the disassembly). This is perfectly reasonable - if there're no reads from buffer afterwards then memset() is useless and if the developers really want to overwrite the buffer thay can use SecureZeroMemory() instead.

However in the following code:

int _tmain(int argc, _TCHAR* argv[])
{
    char buffer[1024] = {};
    MessageBoxA( 0, buffer, buffer, 0 );
    memset( buffer, 0, sizeof( buffer ) );
    Sleep( 0 ); //<<<<<<<<<<<<<<<<<<<<<<<<<<< Extra code
    return 0;
}

the call to memset() is not eliminated. That call has no influence on observed behavior and could be eliminated just as well as in the first snippet.

This can be a compiler deficiency or it can be useful somehow - I can't decide.

Why could leaving memset() call in the machine code emitted for the second snippet be useful?


Solution

  • The compiler probably can't tell that MessageBoxA doesn't create an alias to buffer that's then used by Sleep later. Thus it fails the "as-if" check.