im trying to use the C standard library qsort()
function to sort an
array of bstring and didn't work,
according to bstrlib:
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
my comparator callback is:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
```c
then i setup some simple code to test, call `qsort\_r()` on this data and the array
remains unsorted:
```c
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
the full code is:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include "bstrlib.h"
#define SizeArray(arr) (sizeof((arr)) / sizeof((arr)[0]))
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp((const_bstring)a, (const bstring)b);
}
void print_array(bstring array[], unsigned array_len) {
for (unsigned i=0; i < array_len; i )
printf("[%d] = %s\n", i, array[i]->data);
}
int main(void) {
bstring strings[] = {
bfromcstr("Three"),
bfromcstr("One"),
bfromcstr("Two"),
};
printf("-- Unordered Array --\n");
print_array(strings, SizeArray(strings));
qsort_r(strings, SizeArray(strings), sizeof(bstring), cmp_bstring, NULL);
printf("\n-- Ordered Array --\n");
print_array(strings, SizeArray(strings));
}
The expected output is:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = One
[2] = Three
[3] = Two
but i get:
-- Unordered Array --
[0] = Three
[1] = One
[2] = Two
-- Ordered Array --
[0] = Three
[1] = One
[2] = Two
by the way, why SizeArray
macro didn't work if i use it into print_array()
function (returns 1), and from main()
returns correct array size?
Built with GCC on Linux
CodePudding user response:
You have become confused about levels of indirection. Pretend that you don't know the definition of bstring
, and in particular, you don't know that it is a pointer type. Would you then think it made sense to convert pointers into bstring
s?
qsort()
's comparison function receives pointers to the values being compared, not the values themselves. Therefore, you appear to be looking for this variation:
int cmp_bstring(const void *a, const void *b, void *unused) {
(void)unused;
return bstrcmp(*(const_bstring *)a, *(const bstring *)b);
}