Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are IsEqualGUID() and "operator ==" for GUID declared to return int?

Windows SDK features IsEqualGUID() function and operator==() for two GUIDs that return BOOL (equivalent to int):

// Guiddef.h
#ifdef __cplusplus
__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
{
    return !memcmp(&rguid1, &rguid2, sizeof(GUID));
}
#else   // ! __cplusplus
    #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
#endif
//also in Guiidef.h
#ifdef __cplusplus
__inline int operator==(REFGUID guidOne, REFGUID guidOther)
{
    return IsEqualGUID(guidOne,guidOther);
}
#endif

What's the point in that int? I understand that C doesn't have bool datatype, but there's an #ifdef __cplusplus around, so this code will only be compiled as C++, so bool will be supported anyway. Having a negation near memcmp() effectively transforms all possible values returned from memcmp() into zero and nonzero.

Also there're no user-defined operators in C - only C++ supports them. So the operator== would not compile in C code anyway.

Are there any reasons for choosing int instead of bool here?

like image 996
sharptooth Avatar asked Jul 13 '10 09:07

sharptooth


2 Answers

Because the Windows API exposes IsEqualGUID() as a function returning a BOOL. They need to keep a stable interface. BOOL and bool are different sizes, and the Windows API is designed to be compatible with a variety of languages and compilers. Remember that there are other languages other than C++ that interact with the Windows API.

On C and C++, IsEqualGUID() is implemented in terms of memcmp(), but IsEqualGUID() is also implemented in ole32.dll. You can obtain the function from ole32.dll:

REFGUID guid1 = IID_IUnknown;
REFGUID guid2 = IID_AsyncIUnknown;
typedef BOOL (WINAPI *IsEqualGUIDFuncType)(REFGUID, REFGUID);
HMODULE h = ::LoadLibrary("ole32.dll");
IsEqualGUIDFuncType f = reinterpret_cast<IsEqualGUIDFuncType>
    (::GetProcAddress(h, "IsEqualGUID"));
if(f != NULL)
{
    if(f(guid1, guid2) != 0)
        ::printf("true\n");
    else
        ::printf("false\n");
}
::FreeLibrary(h);

So even though it's implemented as an inline function in C++, other languages may use the DLL implementation of IsEqualGUID(). The C++ version returns a BOOL so it is consistent with the API.

like image 165
In silico Avatar answered Oct 17 '22 09:10

In silico


Are there any reasons for choosing int instead of bool here?

There may be more than one reason:

  • consistency of the interface between C and C++ may be desired by the designers

  • backwards compatibility: The Windows SDK has been kept (roughly) backwards compatible since the big bang (or immediately afterwards). This ensures that client code will require less effort to port to a new Windows version and that new Windows versions will have more of an applications base when released (old applications that keep working on new Windows with minimal effort).

  • using only C language types may be desired for interoperability with C

  • the boolean type may not be supported on some platforms - like Windows CE development (I'm not sure if this is actually the case).

like image 24
utnapistim Avatar answered Oct 17 '22 09:10

utnapistim