Есть ли причина предпочитать memset / ZeroMemory инициализации значения для структур WinAPI? - PullRequest
14 голосов
/ 04 октября 2010

В Win32-программировании используется несколько структур POD.Эти структуры часто необходимо обнулять перед использованием.

Это можно сделать, вызвав memset() / ZeroMemory()

STRUCT theStruct;
ZeroMemory( &theStruct, sizeof( theStruct ) );

или инициализировав значение:

STRUCT theStruct = {};

Хотя два приведенных выше варианта в целом не эквивалентны :

  • по-разному трактуют заполнение
  • по-разному обрабатывают переменные, не являющиеся членами POD

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

Существуют ли случаи, когда memset() / ZeroMemory() следует использовать вместо инициализации значения в структурах Win32 POD?

Ответы [ 7 ]

23 голосов
/ 04 октября 2010

Я всегда использую:

STRUCT theStruct = {}; // for C++, in C use {0}

Это короче, стандартно, поэтому более элегантно, и меня не волнуют теоретические различия.Мы говорим о коде для конкретной ОС здесь.

Еще одним преимуществом является то, что вы также можете сразу установить размер структуры в первом члене, например так:

STRUCT theStruct = {sizeof(STRUCT)}; 

Многие структуры Win32 требуют установки размера в первом элементе.

9 голосов
/ 01 октября 2012

В Win32 ZeroMemory - это просто макрос вокруг RtlZeroRemory, который является макросом для memset. Так что я не думаю, что это имеет значение.

WinBase.h:

\#define ZeroMemory RtlZeroMemory"

WinNT.h:

\#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
4 голосов
/ 26 августа 2013

Если ваш код послужит примером для бесчисленных разработчиков Visual Basic, которые, вероятно, не заметят или не поймут конструкцию C ++ = {}, ZeroMemory - хороший способ сделать код C ++ похожим на псевдокод и минимизировать вероятность появлениятонкие, потрясающие ошибки инициализации.

Это проблема, с которой сталкивались авторы статьи *1004* MSDN, что объясняет, почему ZeroMemory появляется в таком большом количестве кода (даже кода C ++).

С другой стороны, если целью вашего кода C ++ является создание рабочего продукта, а не обучение всему миру, использование изящной и выразительной силы языка C ++ - отличная идея.

2 голосов
/ 04 октября 2010

Единственная причина, по которой memset / ZeroMemory предпочтительнее для такого рода инициализации, заключается в том, что функции WinAPI требуют / ожидают , что память будет инициализирована таким образом, т.е. если функции WinAPI ожидают, что их нули будутфизические нули - значения с шаблонами из всех нулей.

Имейте в виду, что разница между представлением нулевого значения некоторого типа и физическим шаблоном из всех нулей зависит от реализации компилятора, а не от ОС,Теоретически, компилятор Windows может использовать ненулевые битовые шаблоны для представления нулевых значений различных типов.Например, нулевой указатель может быть представлен ненулевым физическим значением в каком-то воображаемом компиляторе C или C ++ для Windows.(Конечно, никто этого не сделает).

2 голосов
/ 04 октября 2010

Единственная причина (которую я могу предвидеть) не использовать инициализацию значения для «обнуления» - это если у вас есть специальные версии memset / ZeroMemory (например, основанные на SSE), или вам нужно избегать проблемс помощью компилятора (ссылаясь на MSVC здесь, начиная с VS2008 memset никогда не станет внутренним, но с некоторым умным кодированием (без использования asm) вы можете принудительно вызвать внутреннее (REP STOS))

1 голос
/ 04 октября 2010

Конечный результат идентичен (при условии, что 0 всегда представлен нулевыми битами ), так что это в значительной степени вопрос стиля. Лично я предпочитаю инициализацию значений, поскольку она проще и не требует вызовов функций.

Кстати, вы должны инициализировать хотя бы одного участника:

STRUCT theStruct = {0};

Пропуск 0 допускается некоторыми компиляторами Си, но не стандартом Си. C ++ допускает упущение, но я предпочитаю просто всегда использовать 0.

0 голосов
/ 08 декабря 2014

в c ++ 11:

struct A {
    int x = 10;
    int y = 100;
    int z = 0;
};

старый стиль c ++

struct A {
    int x;
    int y;
    int z;
    A() : x( 10 ), y( 100 ), z( 0 ) {} //constructor
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...