0

Consider this code:

constexpr size_t size = 32;
constexpr size_t count = 8;
using WordCode = unsigned;

template<typename T>
int CmpHashArray(const T *l,const T *r)
{
    auto * l1 = reinterpret_cast<const __int32*>(l);
    auto * r1 = reinterpret_cast<const __int32*>(r);
    if(*l1 == *r1)
        return 0;
    if(*l1 < *r1)
        return -1;
    return 1;
}

int CmpHashArray2(const WordCode *l,const WordCode *r)
{
    return memcmp(l, r, size);
}
int main(...)
{
  WordCode a1[count], a2[count];
  CmpHashArray(a1, a2);
  CmpHashArray2(a1, a2); 
}

is CmpHashArray have Undefined Behavior? Because with -O2 it takes 2 asm instructions instead of memcmp.

UPD:

Thanks for answer. As i see now, CmpHashArray can boil down to 1 compare if sizeof(array) <= 64bit

if this code can run faster memcmp?(on 64 and 32bit systems, crossplatform)

    template<typename T, 
             size_t count, 
             typename std::enable_if<count*sizeof(T) % 64 == 0>::type
            >
int CmpHashArray(const T *l,const T *r)
{
    auto * l1 = reinterpret_cast<const __int64*>(l);
    auto * r1 = reinterpret_cast<const __int64*>(r);
    size_t iterCount = count*sizeof(T) / 64;
    while(iterCount--) {
        if(*l1 == *r1)
            return 0;
        if(*l1 < *r1)
            return -1;
        else
            return 1;
        ++l1;
        ++r1;
    }
}
user5821508
  • 332
  • 2
  • 10
  • CmpHashArray does not have undefined behaviour, but it will not produce the same results as using `memcmp`. `memcmp` will continue comparing characters either up to `size` or until the characters stop equalling eachother. http://www.cplusplus.com/reference/cstring/memcmp/ – Nonanon Nov 23 '16 at 11:45
  • why the results will be different? – user5821508 Nov 23 '16 at 11:57
  • 1
    Because it only compares the first word, instead of every word in the array. – Sam Varshavchik Nov 23 '16 at 12:00
  • I would use `std::enable_if` to ensure that `sizeof(T)==sizeof(__int32)` or `sizeof(T)%sizeof(__int32)==0` to prevent UB when calling the function on a smaller type. In case of arrays this might become more difficult to ensure... – Simon Kraemer Nov 23 '16 at 12:02
  • To expand on @SamVarshavchik answer: the size argument you're giving memcmp indicates that 32 *bytes* need to be checked, whereas CmpHashArray compares two integers of 32 *bits* – dhavenith Nov 23 '16 at 12:03
  • `CmpHashArray()` isn't comparing 8 words, it's only comparing the first word. `*pointerToSomething == *otherPointerToSomething` has no information about the amount of `Something` that is being pointed at, so it compares only the one `Something`.. – dhavenith Nov 23 '16 at 12:09
  • Also, since you appear to be interested in comparing `__int32`s, whether `memcmp()` does what you intended is platform dependent (i.e. little endian vs. big endian). – dhavenith Nov 23 '16 at 12:11
  • but both arguments have the same byte order, so it shouldnt be a problem – user5821508 Nov 23 '16 at 12:28

0 Answers0