What happens if we don't return 0 from std::qsort?

Viewed 81

According to the documentation qsort is supposed to be used like:

std::qsort(a, size, sizeof *a, [](const void* a, const void* b)
    {

        if(*a < *b) return -1;
        if(*a> *a) return 1;
        return 0;
    });

If the values are the same and I don't mind which comes first, or I prefer one to come before the other based on some other variable, can I do?

if(*a < *b) return -1;
else return 1;
1 Answers

According to the C11 standard (7.22.5/4),

When the same objects (consisting of size bytes, irrespective of their current positions in the array) are passed more than once to the comparison function, the results shall be consistent with one another. That is, for qsort they shall define a total ordering on the array, and for bsearch the same object shall always compare the same way with the key.

Your comparison function violates this requirement, because it returns 1 whenever the two values are equal. When qsort compares two equal values x and y using your comparison function, it will return 1, telling qsort that x > y. If later it compares y and x, then the comparison function will again return 1, meaning that y > x. These two results are not consistent with each other.

This requirement is incorporated by reference into C++17 ([alg.c.library]/2). Because the requirement is violated, the behaviour is undefined.

Related