Search code examples
c++sortinggeneric-programmingqsortmove-semantics

What kinds of types does qsort not work for in C++?


std::sort swaps elements by using std::swap, which in turn uses the copy constructor and assignment operators, guaranteeing that you get correct semantics when exchanging the values.

qsort swaps elements by simply swapping the elements' underlying bits, ignoring any semantics associated with the types you are swapping.

Even though qsort is ignorant of the semantics of the types you are sorting, it still works remarkably well with non-trivial types. If I'm not mistaken, it will work with all standard containers, despite them not being POD types.

I suppose that the prerequisite for qsort working correctly on a type T is that T is /trivially movable/. Off the top of my head, the only types that are not trivially movable are those that have inner pointers. For example:

struct NotTriviallyMovable
{
    NotTriviallyMovable() : m_someElement(&m_array[5]) {}

    int m_array[10];
    int* m_someElement;
};

If you sorted an array of NotTriviallyMovable then the m_someElements would end up pointing to the wrong elements.

My question is: what other kinds of types do not work with qsort?


Solution

  • This doesn't work either for types that have pointers to "related" objects. Such pointers have many of the issues associated with "inner" pointers, but it's a lot harder to prove precisely what a "related" object is.

    A specific kind of "related" objects are objects with backpointers. If object A and B are bit-swapped, and A and C pointed to each other, then afterwards B will point to C but C will point to A.