0
votes

I am trying to port my working code from Mac OS X to GNU/Linux.
I am using qsort_r whose prototypes are different on FreeBSD and GNU/Linux.

Therefore I wrapped my qsort_rspecific calls around platform specific macros Now when I compile, the code compiles and runs fine on Mac OS X, but I get errors on GNU/Linux

I can't seem to find the issue. Maybe another pair of eyes might help.

error -

auto-assign.c: In function ‘get_gtype’:
auto-assign.c:1669:19: error: assignment from incompatible pointer type [-Werror]
auto-assign.c:1677:19: error: assignment from incompatible pointer type [-Werror]
auto-assign.c:1685:19: error: assignment from incompatible pointer type [-Werror]
auto-assign.c:1693:19: error: assignment from incompatible pointer type [-Werror]

auto_assign.c -

switch (op) {
1668 case RULE_S2_8:
1669 gtype->qsort_comp = comp_uint8_t; # -Werror
1675 break;
1676 case RULE_S2_16:
1677 gtype->qsort_comp = comp_uint16_t; # -Werror
1683 break;
1684 case RULE_S2_32:
1685 gtype->qsort_comp = comp_uint32_t; # -Werror
1691 break;
1692 case RULE_S2_64:
1693 gtype->qsort_comp = comp_uint64_t; # -Werror
1699 break;
1700 }

gtype -

struct grouper_type {
 71 #if defined(__APPLE__) || defined(__FreeBSD__)··
 72   int (*qsort_comp)(
 73                     void*                           thunk,
 74                     const void*                     e1,
 75                     const void*                     e2
 76                    );
 77 #elif defined(__linux)
 78   int (*qsort_comp)(
 79                     const void*                     e1,
 80                     const void*                     e2,
 81                     void*                           thunk
 82                    );
 83 #endif
 ...

-> gcc -E does return me the write qsort_comp on both platforms.


comp_* -

532 #if defined(__APPLE__) || defined(__FreeBSD__)
533   #define comp(size) \
534   int comp_##size(void *thunk, const void *e1, const void *e2) {\
535     size x, y; \
536     x = *(size *)(**(char ***)e1+*(size_t *)thunk); \
537     y = *(size *)(**(char ***)e2+*(size_t *)thunk); \
538     return (x > y) - (y > x); \
539   }
540 #elif defined(__linux)
541   #define comp(size) \
542   int comp_##size(const void *e1, const void *e2, void *thunk) {\
543     size x, y; \
544     x = *(size *)(**(char ***)e1+*(size_t *)thunk); \
545     y = *(size *)(**(char ***)e2+*(size_t *)thunk); \
546     return (x > y) - (y > x); \
547   }
548 #endif
549 
550 comp(uint8_t);
551 comp(uint16_t);
552 comp(uint32_t);
553 comp(uint64_t);
...

-> gcc -E does return me the write comp_* on both platforms.

2
I would strongly suggest running gcc -E to see the preprocessed result of that complicated macro; I can't be bothered to translate it in my head! - Oliver Charlesworth
@OliCharlesworth I did, the preprocessed code is just fine on both platforms. - Vaibhav Bajpai
Where is the definition of gtype->qsort_comp ? if the two disagree one of them must be wrong - wildplasser
Well, something is clearly wrong... Can you boil this down to a much simpler test-case (i.e. an SSCCE) that avoids the macros, but that still provokes the same error? - Oliver Charlesworth
Maybe the evaluation of #if defined(__APPLE__) || defined(__FreeBSD__) is different for the definition of gtype->qsort_comp (missed include file) ? - wildplasser

2 Answers

0
votes

You are removing a const qualifier in the macro.

0
votes

I seem to have found the issue. I forgot to wrap the function prototypes.

154 #if defined (__APPLE__) || defined (__FreeBSD__)
155 int·
156 comp_uint8_t(void *thunk, const void *e1, const void *e2);
157 int·
158 comp_uint16_t(void *thunk, const void *e1, const void *e2);
159 int·
160 comp_uint32_t(void *thunk, const void *e1, const void *e2);
161 int·
162 comp_uint64_t(void *thunk, const void *e1, const void *e2);
163 #elif defined(__linux)
164 int·
165 comp_uint8_t(const void *e1, const void *e2, void* thunk);
166 int·
167 comp_uint16_t(const void *e1, const void *e2, void* thunk);
168 int·
169 comp_uint32_t(const void *e1, const void *e2, void* thunk);
170 int·
171 comp_uint64_t(const void *e1, const void *e2, void* thunk);
172 #endif