views:

127

answers:

3

Many Win32 API functions have parameters specified to be "out". For example, GetIconInfo() description says about the second parameter that The function fills in the structure's members.

This implies that the function doesn't ever read the original values stored in the "out" parameter - only changes them - and therefore the caller is free to skip initialization.

Yet in one project I see the following:

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);
}

Is there any sense in that SecureZeroMemory() call? What could happen without it?

+1  A: 

Nothing. I mean if one is pretty sure that whatever is written there before call is discarded then there is no reason for doing that. But we don't know how internally the API will function unless we developed the API, then it would be a good idea to initialize it.

Himanshu
+4  A: 

Well, in general I think initialisation is not needed, but good practice if you don't know exactly what the called function does with the values in the output variable. In this specific case, the ICONINFO structure has two HBITMAP members which are essentially pointers to bitmaps. In the general case I'd say that if you are passing pointers to a function then you have to be certain that:

  1. You pass in pointers that point to nothing and the function you call creates the thing pointed to for you and makes sure your pointer points to it. (and probably leaves you to manage the newly allocated stuff) or
  2. You pass in a pointer that points to something (i.e. you allocated something for it) and the function uses what you allocated.

The GetIconInfo() function fits the first case. So for clarity and perhaps even security it looks like a good idea to me to ensure the HBITMAP members of the ICONINFO structure are actually zero, rather than a random value that can lead to all kinds of nastiness further down the road.

So my verdict in this case would also be: not necessary but good practice.

jilles de wit
+1  A: 

This implies that the function doesn't ever read the original values stored in the "out" parameter - only changes them - and therefore the caller is free to skip initialization.

Perhaps it isn't about the function reading the fields. Maybe its for detecting fields unfilled by the function? I don't know if this is necessary in this case, just pointing out that it might not be about reading.

Rafał Dowgird