afoken:

Update: I think I misunderstood what was wanted originally (removal of warnings and minimization of unused code), so while my original answer did what I wanted it to do, I doubt it did what afoken wanted done. So here's what I think you want.

First, you can create a library of the various methods you may want to include:

$ 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

Now your program can simply use the extern directive to tell the linker which items to pull into your executable:

$ cat foo.c #include <stdio.h> #include <stdlib.h> #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<sizeof(a1)/sizeof(a1[0]); i++) { printf("%d, ", a1[i]); } #endif #if defined(DO_DOUBLE) printf("\n\n"); CFG_ADD(double); qsort(a2, sizeof(a2)/sizeof(a2[0]), sizeof(a2[0]), cmp_fn); for (int i=0; i<sizeof(a2)/sizeof(a2[0]); i++) { printf("%f, ", a2[i]); } #endif } $ gcc foo.c -DDO_INT -L. -ltypes -o foo_int $ gcc foo.c -DDO_DOUBLE -L. -ltypes -o foo_double $ gcc foo.c -DDO_INT -DDO_DOUBLE -L. -ltypes -o foo_both

And you can tell that the linker did what it wanted:

$ ./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

I hope this gets you where you want to go...

My original response was:

If you don't mind it, you could use a function pointer to hold the sorting function, and let your macro set the value, like:

$ cat foo.c #include <stdio.h> #include <stdlib.h> 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<sizeof(a1)/sizeof(a1[0]); i++) { printf("%d, ", a1[i]); } printf("\n\n"); CFG_ADD(double); qsort(a2, sizeof(a2)/sizeof(a2[0]), sizeof(a2[0]), cmp_fn); for (int i=0; i<sizeof(a2)/sizeof(a2[0]); i++) { printf("%f, ", a2[i]); } } $ gcc foo.c -o foo $ ./foo 1, 5, 25, 50, 100, 1.000000, 5.000000, 10.000000, 25.000000,

If that's not good for you, let me know and I'll try to think up something else.

...roboticus

When your only tool is a hammer, all problems look like your thumb.


In reply to Re: [OT] Abusing the C preprocessor by roboticus
in thread [OT] Abusing the C preprocessor by afoken

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.