Должен ли вызывающий объект инициализировать параметры out? - PullRequest
1 голос
/ 06 января 2010

Многие функции Win32 API имеют параметры, указанные как "out". Например, GetIconInfo () description говорит о втором параметре, который Функция заполняет элементы структуры .

Это означает, что функция никогда не считывает исходные значения, сохраненные в параметре "out" - только изменяет их - и, следовательно, вызывающая сторона может пропустить инициализацию.

Еще в одном проекте я вижу следующее:

ICONINFO ii;
::SecureZeroMemory(&ii, sizeof(ICONINFO));
if (::GetIconInfo(hIcon, &ii))
{
    //do stuff, then
    //release bitmaps
    if(ii.hbmMask)
        ::DeleteObject(ii.hbmMask);
    if(ii.hbmColor)
        ::DeleteObject(ii.hbmColor);
}

Есть ли смысл в этом SecureZeroMemory() звонке? Что может случиться без этого?

Ответы [ 3 ]

4 голосов
/ 06 января 2010

Ну, в общем, я думаю, что инициализация не нужна, но хорошая практика, если вы не знаете точно, что вызывает вызываемая функция со значениями в выходной переменной. В этом конкретном случае структура ICONINFO имеет два элемента HBITMAP, которые по существу являются указателями на растровые изображения. В общем случае я бы сказал, что если вы передаете указатели на функцию, вы должны быть уверены, что:

  1. Вы передаете указатели, которые указывают на ничто, и функция, которую вы вызываете, создает вещь указал на вас и удостоверяется Ваш указатель указывает на это. (и, вероятно, оставляет вас управлять вновь выделенными вещами) или
  2. Вы передаете указатель, который указывает на что-то (т.е. вы выделили что-то для этого) и Функция использует то, что вы выделили.

Функция GetIconInfo() соответствует первому случаю. Поэтому для ясности и, возможно, даже для безопасности, мне кажется хорошей идеей обеспечить, чтобы HBITMAP члены структуры ICONINFO были фактически нулевыми, а не случайным значением, которое может привести к всевозможным неприятностям в будущем.

Так что мой вердикт в этом случае также будет: не обязательно, но хорошая практика .

1 голос
/ 07 января 2010

Это означает, что функция никогда не считывает исходные значения, сохраненные в «out» параметр - только изменяет их - и, следовательно, вызывающая сторона может пропустить инициализацию.

Возможно, дело не в функции чтения полей. Может быть, для обнаружения полей, не заполненных функцией? Я не знаю, нужно ли это в этом случае, просто указав, что речь не идет о чтении.

1 голос
/ 06 января 2010

Ничего. Я имею в виду, что если кто-то уверен, что все, что написано там до вызова, отбрасывается, то для этого нет причин. Но мы не знаем, как внутренне API будет функции, если мы не разработали API, то было бы неплохо инициализировать его.

...