I'm a C++ programmer for the most part, but just for fun I was trying to do some generic programming in C. In particular, I implemented a generic sorting algorithm. The signature of my function is
int sort(void *data,
size_t num_elems,
size_t elem_size,
int (*cmp)(const void*, const void*))
When I compared this to qsort()
in the standard library, I noticed that unlike my function, qsort()
does not have a return value. Since sorting an array will always require swapping elements, the implementation requires a temporary storage of size elem_size
. As C doesn't have templates, elem_size
is not known at compile time, so the temporary storage must be allocated dynamically, which could fail. In that case, qsort()
couldn't sort the array, but it couldn't report the error either, so there is no way of knowing if the array is sorted upon return.
Am I missing something here?
Any partitioning algorithm needs to be able to swap two elements, and the qsort
API means that the code doesn't know how big they are at compile-time. But they don't need to be swapped as a whole; they can be swapped one byte at a time. (That's effectively what memcpy would do anyway.)
The following comment and macro are right at the beginning of qsort.c
in the Gnu libc implementation. (Note that the code is subject to the LGPL)
/* Byte-wise swap two items of size SIZE. */
#define SWAP(a, b, size) \
do \
{ \
size_t __size = (size); \
char *__a = (a), *__b = (b); \
do \
{ \
char __tmp = *__a; \
*__a++ = *__b; \
*__b++ = __tmp; \
} while (--__size > 0); \
} while (0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With