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.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.