I am writing a function that receives a pointer to a comparison function and an array of MyStructs
and is supposed to sort the array according to the comparison function:
void myStructSort(
struct MyStruct *arr,
int size,
int (*comp)(const struct MyStruct *, const struct MyStruct *)) {
qsort(arr, size, sizeof(struct MyStruct), comp);
}
Unfortunately this doesn't compile because qsort
expects the comparator to receive void *
arguments and not const struct MyStruct *
. I thought of several bad solutions and was wondering what the correct solution is.
Option 1
Cast comp
to int (*)(const void *, const void*)
. This compiles but is undefined behavior (see this SO question).
Option 2
Create a global variable int (*global_comp)(const struct MyStruct *, const struct MyStruct *)
and set global_comp=comp
inside myStructSort
. Then create a function:
int delegatingComp(const void *a, const void *b) {
return globalComp((const struct MyStruct *)a, (const struct MyStruct *)b);
}
And in myStructSort
call qsort(arr, size, sizeof(struct MyStruct), delegatingComp)
. The problem with this is the icky global variable.
Option 3
Reimplement qsort
. This is functionally safe but very bad practice.
Is there a magical perfect fourth option?
Edit
I can't change the API of myStructSort
and I am compiling my code using gcc c99 -Wall -Wextra -Wvla
.