I’m curious if it’s a good idea to use a union when accessing Win32 APIs that return variable length structures, to avoid manually managing the allocated memory.
Consider the following:
void displayServices(std::wostream& log, std::tr1::shared_ptr<void> manager, LPENUM_SERVICE_STATUS currentServiceToDisplay, DWORD number, bool whitelist)
{
static union //Don't care about being thread safe
{
QUERY_SERVICE_CONFIG svcConfig;
unsigned char bufferSizer[8000];
};
for(DWORD idx = 0; idx < number; currentServiceToDisplay++, idx++)
{
DWORD garbage = 0;
std::tr1::shared_ptr<void> currentServiceHandle(
OpenService(reinterpret_cast<SC_HANDLE>(manager.get()), currentServiceToDisplay->lpServiceName, SERVICE_QUERY_CONFIG),
serviceCloser);
QueryServiceConfig(reinterpret_cast<SC_HANDLE>(currentServiceHandle.get()),
&svcConfig, 8000, &garbage);
//Use svcConfig for something here.
}
}
Are there any major issues with this?
One problem with your union approach is that the whole idea of using an union is rather forced and completely unnecessary. All you seem to want to do is the replace dynamic memory allocation with a local static buffer of some “large” size. Then just do it explicitly
What you were trying to achive by using union specifically is not clear to me. Do you think that the approach with the union is somehow more elegant? I don’t think so.
Update: It has been noted in one of the comments that this approach allegedly might not work with a compiler performing strict aliasing optimizations. The comment is absolutely incorrect for more than one reason. Firstly, the above approach does not rely on any aliasing-dependent behavior at all, since all access is supposed to be performed through
svcConfigpointer andsvcConfigpointer only. Secondly, strict aliasing optimizations are never performed if the aliased data is a character array. The language specification explicitly permits aliased access through character arrays, which is why all optimizing compilers disable their strict aliasing optimizations when a character array is involved. Any compiler that fails to do so is broken and thus not worth consideration.