Search code examples
c++arraysvoid-pointersqsortstrict-aliasing

Using Sub-Vectors With qsort


I wrote an answer here to use qsort to sort an array-of-arrays. I could not use sort on account of it's use of the assignment operator in swap operations.

I believe that the stipulation on my answer working is:

The type of the elements of the array must be a TrivialType, otherwise the behavior is undefined

So my question is: Is int[2] a "TrivialType"?


The actual code in answer that prompted this question is:

int array[5][2] = { {20, 11}, {10, 20}, {39, 14}, {29, 15}, {22, 23} };
static const auto SIZE = size(*array);

qsort(array, size(array), sizeof(*array), [](const auto lhs, const auto rhs) {
    const auto first = reinterpret_cast<const int*>(lhs);
    const auto last = next(first, SIZE);
    const auto its = mismatch(first, last, reinterpret_cast<const int*>(rhs));

    if (its.first == last) {
        return 0;
    } else if (*its.first < *its.second) {
        return -1;
    } else {
        return 1;
    }});

Solution

  • A int is a Arithmetic type per [basic.fundamental] and a Arithmetic type is also called a scalar type per [basic.types]/9

    Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_-t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types.

    and then we have

    Scalar types, trivial class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called trivial types

    emphasis mine

    So an scalar type and an array of a scalar are both trivial types.

    All quotes from draft N3797