Почему компилятор C ++ исключает бесполезные записи, только если после этих записей нет кода? - PullRequest
6 голосов
/ 01 сентября 2011

Я проверяю возможности оптимизации Visual C ++ 10 и обнаружил довольно любопытную вещь.Весь код здесь скомпилирован с /O2.

В следующем коде:

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

вызов memset() до return исключен из машинного кода (я проверяю разборку).Это вполне разумно - если после этого нет чтения с buffer, то memset() бесполезно, и если разработчики действительно хотят перезаписать буфер, они могут вместо этого использовать SecureZeroMemory().

Однако в следующем коде:

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;
}

звонок на memset() не исключен.Этот вызов не влияет на наблюдаемое поведение и может быть устранен так же, как и в первом фрагменте.

Это может быть недостатком компилятора или каким-то образом полезным - я не могу решить.

Почему полезно оставить memset() вызов в машинном коде, отправляемом для второго фрагмента?

Ответы [ 2 ]

18 голосов
/ 01 сентября 2011

Компилятор, вероятно, не может сказать, что MessageBoxA не создает псевдоним для buffer, который затем используется Sleep позже. Таким образом, он не проходит проверку «как будто».

2 голосов
/ 01 сентября 2011

Компилятор может посмотреть содержимое memset и определить, что он делает. Sleep() - системный вызов, взаимодействующий с ядром, и его поведение зависит от версии Windows, в которой выполняется код; в том числе возможность еще реализованных версий Windows. У компилятора просто нет возможности узнать, что будет делать функция, и поэтому нет способа ее оптимизировать.

То же самое можно сказать о MessageBox, что меня удивляет, что memset был удален в первой версии.

Можно с уверенностью сказать, что вызов memset не будет проблемой для любой текущей или будущей версии Windows, но я не хочу, чтобы компилятор пытался об этом догадаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...