• XSS.stack #1 – первый литературный журнал от юзеров форума

Оптимизатор студии

PlebsoVata

RAID-массив
Пользователь
Регистрация
05.10.2019
Сообщения
87
Реакции
34
Сегодня случайно обнаружил следующую фишку студии, что при оптимизациях она сама вставляет в некоторых случаях функцию _memset.
Проект самый обычный, в котором выключен весь CRT, но оптимизатор студии из-за этого как раз и не дает скомпилировать нашу программку.
Причем для этого достаточно такого кода:
C++:
int SomeFunc()
{
    char* some_chars = (char*)HeapAlloc(GetProcessHeap(), 0, 1024);

    for (int i = 0; i < 1024; ++i)
        some_chars[i] = 0;

    return some_chars[10];
}
При /Od все впорядке, но при /O1 или /O2 линкер будет жаловаться, что не находит _memset, можно ли как-то это пофиксить, чтобы оставить уровень оптимизации на /O1 или /O2, но выключить конкретно эту оптимизацию через _memset.

Можно конечно статически слинковать, но хотелось бы без этого или все-таки студия сама окончательно погрязла в CRT?
#pragma comment(lib, "libvcruntime.lib")

Может кто знает, есть ли еще подобные подводные камни в студии?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Попробуй так:
#pragma function(memset)
void * __cdecl memset(void *pTarget, int value, size_t cbTarget)
{
unsigned char *p = static_cast<unsigned char *>(pTarget);
while(cbTarget-- > 0)
{
*p++ = static_cast<unsigned char>(value);
}
return pTarget;
}
 
Попробуй так:
#pragma function(memset)
void * __cdecl memset(void *pTarget, int value, size_t cbTarget)
{
unsigned char *p = static_cast<unsigned char *>(pTarget);
while(cbTarget-- > 0)
{
*p++ = static_cast<unsigned char>(value);
}
return pTarget;
}
Спасибо, это помогло, если знаешь, то можешь кинуть ссылки на то, где можно почитать о #pragma function и прочих подобных ништячках более подробно, потому что в msdn написано что это переключает вызов функции с интринсика на не интринсик версию функции и там нет например твоего примера, сори за тавтологию
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Да вроде достаточно простым языком описано:
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Это никак не пофиксить, нужно вставлять через вот эту прагму. Причем не только memset, а и memcpy и еще там что-то всплывает по ходу дела.

Это один из моментов, за что я не люблю студию. В каком-нибудь Pelles C это решается 1 опцией, и компилятор подставляет какой-нибудь rep movsb. Но негрософт такое не умеет почему-то.
 
Это никак не пофиксить, нужно вставлять через вот эту прагму. Причем не только memset, а и memcpy и еще там что-то всплывает по ходу дела.

Это один из моментов, за что я не люблю студию. В каком-нибудь Pelles C это решается 1 опцией, и компилятор подставляет какой-нибудь rep movsb. Но негрософт такое не умеет почему-то.
memcpy скорее всего будет в конструкциях такого вида
this_arr[index] = other_arr[index];
Кстати проблема не только студии, clang почему то также делает, а вот gcc обходится без memset, memcpy, можно тут проверить например такой код с флагом -О2:
C++:
#include <stdio.h>
#include <memory>

int main()
{
    char* some_arr = (char*)malloc(1024);
    char* new_arr = (char*)malloc(1024);

    for (int i = 0; i < 1024; ++i)
    {
        some_arr[i] = 0;
        new_arr[i] = i + i * 0x256;
    }
    puts(new_arr);
    puts(some_arr);

    for (int i = 0; i < 1024; ++i)
    {
        new_arr[i] = some_arr[i];
    }   
    puts(new_arr);
    return some_arr[5];
}
Если в кланге можно включить подобную gcc генерацию кода, т.е. без memset'ов и прочего, то можно в принципе жить, потому что в студию интегрирован кланг и тогда можно с помощью него компилировать
 

Думаю это оно
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх