$ cat lib_int.c int compare_int(const void *a, const void *b) { return *(int *)a - *(int *)b; } $ cat lib_double.c int compare_double(const void *a, const void* b) { return *(double *)a - *(double *)b; } $ gcc -c -o lib_int.o lib_int.c $ gcc -c -o lib_double.o lib_double.c $ ar cr libtypes.a lib_int.o lib_double.o #### $ cat foo.c #include #include #if defined(DO_INT) int a1[] = { 1, 100, 5, 50, 25 }; #endif #if defined(DO_DOUBLE) double a2[] = { 1.0, 10.0, 5.0, 25.0 }; #endif int (*cmp_fn)(const void *, const void *); #define CFG_ADD(TYPE) \ extern int compare_ ## TYPE(const void*, const void*); \ cmp_fn = compare_ ## TYPE int main(int argc, char **argv) { #if defined(DO_INT) CFG_ADD(int); qsort(a1, sizeof(a1)/sizeof(a1[0]), sizeof(a1[0]), cmp_fn); for (int i=0; i## $ ./foo_int 1, 5, 25, 50, 100, $ ./foo_double 1.000000, 5.000000, 10.000000, 25.000000, $ ./foo_both 1, 5, 25, 50, 100, 1.000000, 5.000000, 10.000000, 25.000000, $ nm foo_int.exe | grep compare 0000000100403040 r .rdata$.refptr.compare_int 0000000100403040 R .refptr.compare_int 0000000100401170 T compare_int $ nm foo_double.exe | grep compare 0000000100403040 r .rdata$.refptr.compare_double 0000000100403040 R .refptr.compare_double 00000001004011a0 T compare_double $ nm foo_both.exe | grep compare 0000000100403040 r .rdata$.refptr.compare_double 0000000100403050 r .rdata$.refptr.compare_int 0000000100403040 R .refptr.compare_double 0000000100403050 R .refptr.compare_int 0000000100401230 T compare_double 0000000100401210 T compare_int #### $ cat foo.c #include #include int compare_int(const void *a, const void *b) { return *(int *)a - *(int *)b; } int compare_double(const void *a, const void* b) { return *(double *)a - *(double *)b; } int a1[] = { 1, 100, 5, 50, 25 }; double a2[] = { 1.0, 10.0, 5.0, 25.0 }; int (*cmp_fn)(const void *, const void *); #define CFG_ADD(TYPE) cmp_fn = compare_ ## TYPE; int main(int argc, char **argv) { CFG_ADD(int); qsort(a1, sizeof(a1)/sizeof(a1[0]), sizeof(a1[0]), cmp_fn); for (int i=0; i