when _WIN64
not defined
(*(DWORD *)pGuid->Data4 == 0) && (*(DWORD *)(pGuid->Data4 + 4) == 0);
case - this is absolute safe and correct - the Data4
member is align to DWORD
(4) and have size of 2 DWORD
(2 * sizeof(DWORD) == 8
)
for _WIN64
the align of Data4
still DWORD
(4) because all structure align is 4 ( C_ASSERT(__alignof(GUID)==4)
) - when code (*(DWORD64 *)pGuid->Data4 == 0);
assume 8 byte data align reference. for say x64 usually processor not generate exception when referenced to unaligned data. however on another platform this can be. in any case access to unaligned data bad for performance. so check must be:
BOOL IsEmptyGuid(const GUID * pGuid)
{
return (pGuid->Data1 == 0) &&
(pGuid->Data2 == 0) &&
(pGuid->Data3 == 0) &&
(*(DWORD *)pGuid->Data4 == 0) && (*(DWORD *)(pGuid->Data4 + 4) == 0);
}
for all platforms.
and about member offsets, align etc. it well known and here can not be any UB. otherwise will be impossible any binary interface between to piece of code
interesting, what is not correct here:
Data4
not pointer to 8 continuous bytes ?
Data4
have not 8 bytes offset from GUID ?
Data4
not aligned on 4 byte (of course if pGuid itself properly
aligned) ?
- we can not check 8 byte memory (aligned on
DWORD
) as 2 DWORD
?
and some code from windows headers files:
// Faster (but makes code fatter) inline version...use sparingly
#ifdef __cplusplus
__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
{
return (
((unsigned long *) &rguid1)[0] == ((unsigned long *) &rguid2)[0] &&
((unsigned long *) &rguid1)[1] == ((unsigned long *) &rguid2)[1] &&
((unsigned long *) &rguid1)[2] == ((unsigned long *) &rguid2)[2] &&
((unsigned long *) &rguid1)[3] == ((unsigned long *) &rguid2)[3]);
}
__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
{
return !memcmp(&rguid1, &rguid2, sizeof(GUID));
}
#else // ! __cplusplus
#define InlineIsEqualGUID(rguid1, rguid2) \
(((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \
((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \
((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \
((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3])
#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
#endif // __cplusplus
#ifndef __IID_ALIGNED__
#define __IID_ALIGNED__
#ifdef __cplusplus
inline int IsEqualGUIDAligned(REFGUID guid1, REFGUID guid2)
{
return ((*(PLONGLONG)(&guid1) == *(PLONGLONG)(&guid2)) && (*((PLONGLONG)(&guid1) + 1) == *((PLONGLONG)(&guid2) + 1)));
}
#else // !__cplusplus
#define IsEqualGUIDAligned(guid1, guid2) \
((*(PLONGLONG)(guid1) == *(PLONGLONG)(guid2)) && (*((PLONGLONG)(guid1) + 1) == *((PLONGLONG)(guid2) + 1)))
#endif // !__cplusplus
#endif // !__IID_ALIGNED__