The return value from RtlCompareMemory and memcmp do not mean the same thing!


When I was working on the Bluetooth core, I got this mistake the first time I tried to compare 2 bluetooth addresses (a bluetooth address is 48 bits wide and at the time we were not using a ULONGLONG to represent the address, so we were doing structure comparisons).  The result from RtlCompareMemory is the number of bytes that matched, while the result from memcmp is the standard CRT result for a comparison function where the result is <0 if the first buffer is less then the second buffer, result == 0 if the 2 buffers are equal, and  result >0 when the first buffer is greater then the second.  This made the following code which was trying to compare for equality return the opposite result


typedef struct _BDADDR {
    union {
        struct {
            unsigned int LAP : 24;            
            unsigned int UAP : 8;                          
        };
        unsigned int SAP;                                  
    };


    unsigned short NAP;                                    
} BDADDR, *PBDADDR;


PBDADDR pSrc, pDest;


// initialize pSrc, pDest


if (RtlCompareMemory(pSrc, pDest, sizeof(BDADDR)) == 0x0) {
    // they are equal


which was wrong and corrected to the following correct check


if (RtlCompareMemory(pSrc, pDest, sizeof(BDADDR)) == sizeof(BDADDR)) {
    // they are equal

Comments (3)

  1. hanzhu says:

    I have made the same mistake some times before! :(

  2. PeterWieland says:

    RtlEqualMemory is your friend.

    Friend in the sense that it’s a really confusing distinction that’s not obvious, but once you’re used to it it helps you out of this jam.

  3. RtlEqualMemory is closer to memcmp and is semantically closer to what people want to do 99.99% of the time, but it too suffers from the problem that RtlCompareMemory does when you think it behaves like memcmp.  memcmp returns zero for equality, RtlEqualMemory returns 1 when they are equal.