Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 291
sharptooth Avatar asked Sep 01 '11 12:09

sharptooth


2 Answers

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.

like image 134
Mark B Avatar answered Sep 28 '22 01:09

Mark B


The compiler can look at the contents of memset and determine what it does. Sleep() is a system call that interacts with the kernel and its behavior is dependent on what version of Windows the code is run on; including the possibility of yet to implemented versions of Windows. There is simply no way for the compiler to know what the function will do and therefore there is no way for it optimize around it.

The same can be said of MessageBox which makes me surprised that memset got removed in the first version.

It is a safe bet that the call to memset will not be a problem on any current or future version of Windows, but that's not something I want the compiler to try to guess about.

like image 27
IronMensan Avatar answered Sep 28 '22 02:09

IronMensan