Как заставить компилятор MSVC исключить размещение в стеке больших временных объектов? - PullRequest
0 голосов
/ 11 декабря 2018

Этот вопрос не является дубликатом этого или других подобных вопросов.Этот вопрос касается очистки структуры после , которая была инициализирована и уже использована.


Обновление

После прочтения первых несколькихВаши комментарии Я хотел бы уточнить мой вопрос:

  • Как заставить компилятор MSVC исключить выделение большого стека?

Я обновил заголовок, тексти код ниже, чтобы прояснить это.


Я недавно начал компилировать свои проекты с опциями компилятора /GS, /sdl и /analyze.(Microsoft Visual C ++ 2015) С этими параметрами компилятор правильно предупреждает о сомнительных конструкциях кода.Однако я столкнулся с некоторыми предупреждениями о том, что я всегда считал себя хорошим стилем C ++.

Пожалуйста, взгляните на следующий пример кода:

struct my_struct {
    char  large_member[64000];
};

void do_something_else(my_struct & ms)
{
    // the intent of the next line is to "clear" the ms object
    ms = {};  // <-- here the compiler claims the large stack allocation

   // ... do some more work with ms
}

my_struct oh_my = {}; // construction, apparently no large stack allocation

int main()
{ 
    // ...
    // do something with the oh_my object
    // 

    do_something_else(oh_my);
}

Я былсказал, что стандартный C ++ способ очистки структуры следующий:

ms = {};

С опцией /analyze компилятор предупреждает об этом следующим образом (пример):

C: \ Dev \ MDS \ Proj \ MDSCPV \ Vaps_Common_lib \ camber_radar.cpp: 162: предупреждение: C6262: функция использует «144400» байтов стека: превышает / анализирует: размер стека «16384». Это распределение было длясгенерированный компилятором временный файл для 'struct BitmapBuffer' в строке 162. Рассмотрите возможность перемещения некоторых данных в кучу.

Я думаю, что происходит следующее:

  • временный объект построен настек
  • временный объект копируется в переменную объекта

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

std::memset(&ms, 0, sizeof(ms));

1 Ответ

0 голосов
/ 11 декабря 2018

Поскольку my_struct является тривиально копируемым , компиляторы должны иметь возможность сделать вызов memset вместо создания временного и затем назначить его, но это не обязательно.

Размещение нового выражения решит вашу проблему: он создает объект по заранее выделенному адресу, используя предоставленный конструктор.Например, new(&ms) my_struct{} дает ту же семантику, что и ms = {}.Если my_struct имеет Нетривиальный Деструктор , явный вызов ms.~my_struct() должен предшествовать размещению new.Для справки: новое выражение

Я предлагаю не использовать эту технику обычным способом.Это своего рода «черная магия» низкого уровня C ++.Хорошие компиляторы должны оптимизировать, используя memset.

Кстати, глобальная переменная oh_my не выделяет временное значение в стеке, потому что это Инициализированная константа во время компиляции.

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