Этот вопрос не дублирует этот или другие подобные вопросы. Этот вопрос касается очистки структуры после ее инициализации и использования.
Обновить
Прочитав несколько первых ваших комментариев, я хотел бы уточнить свой вопрос:
- Как я могу заставить компилятор 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' байт стека: превышает / анализирует: stacksize '16384' .. Это выделение было для сгенерированного компилятором временный для 'struct BitmapBuffer' в строке 162. Рассмотрите возможность перемещения некоторых данных в кучу.
Думаю бывает следующее:
- в стеке создается временный объект
- временный объект копируется в объектную переменную
Я бы хотел, чтобы там происходило что-то вроде инициализации по умолчанию. На мой взгляд, компилятор должен иметь возможность оптимизировать распределение стека. Но видимо (по предупреждению) компилятор этого не делает. У меня такой вопрос: Как я могу заставить компилятор исключить выделение стека? Теперь я начал заменять эти места следующим кодом:
std::memset(&ms, 0, sizeof(ms));
/GS /analyze
опциями. (/GS
и/sdl
в некоторой степени исключают друг друга) - person user23573   schedule 11.12.201864000
байта каждая, компилятор имеет все права жаловаться, учитывая, что порог составлял 16384 байта. - person user7860670   schedule 11.12.2018memset
вызов для этой строки: godbolt.org/z/G6CQO_ - person Evg   schedule 11.12.2018/analyze:stacksize1000000
- person tunglt   schedule 11.12.2018ms
похоже на инициализацию по умолчанию) и без выделения стека? - person   schedule 11.12.2018std::memset
, а также о реализации функции-членаclear()
структуры. - person user23573   schedule 11.12.2018const my_struct MY_ZERO_ = {};
, а затем в своей функции, где вам нужно инициализировать вашу переменную:ms = MY_ZERO_;
это стоит только memcpy вместо memset. - person tunglt   schedule 11.12.2018my_struct
и хотите, чтобы он работал в менее тривиальных случаях, которые не могут быть решены простымmemset
, создать новый объект в хранилищеms
, напримерms.~my_struct(); new(&ms) my_struct();
. Это гарантированно будет построено по умолчанию без копирования, но вам нужно быть осторожным, если у вас есть константные или ссылочные элементы данных или базовые подобъекты, и в этом случае нужноstd::launder
все указатели / ссылки на старый объект. - person   schedule 11.12.2018