Hi, in my C project I have five different function (with the same name) which implement one algorithm but in different ways. At compiler time I need to select only one of these functions. Can I implement this using a #define and a bunch of #ifndef? Are there better ways to do this?
In C, that is the only way I know of doing this. C++ you would be in luck.
ifndef macros seem the only possibility at compile time.
You may try with function ptrs at runtime.
Just thought that you may create each function in different file and link the proper one whenever you want. No macros, just a Makefile switch. That way you keep the same signature and decide at link time which implementation to use. Link algo1.o or link algo2.o...
Yes. What you do is say this in the code:
#if defined(FUNC1)
...func1 here
#elif defined(FUNC2)
...func2 here
...ect. ect.
#endif
And then when you compile add the gcc option -DFUNCX for example:
gcc -DFUNC1 -o myprogram myfile.c
Then you can choose which function to compile in by changing the value you put in the -D option. This is very common practice.
if i were you i'd have 5 different function name then use an if statement to figure out which one to call at runtime.
C does not have overloading (operator or otherwise) so there is no other way to do this. I am afraid you are stuck with pre-processor commands.
Probably a more elegant approach would be to define them with 5 different names (e.g. f1, f2, f3, f4, f5), but always call the function using the same different name (e.g. f). Then compile with something like:
gcc -Df=f1
That will compile any calls to f() as a call to f1().
You cannot have two different function with the same name defined within one translation unit.
So I guess you already have the functions separated between different source files. Just include the file you want when you compile ... for example, with gcc
gcc -o testsort main.c bubble.c
gcc -o testsort main.c merge.c
gcc -o testsort main.c radix.c
Where any of bubble.c
, merge.c
, radix.c
(and others) have a function with the same name:
int sort(int *data, size_t len) { /* ... */ }
If you have the source for the functions in separate files (for my example, in f1.c and f2.c), then this scheme works:
$ cat so.c
#define STRINGIZER(x) #x
#define HEADER(x) STRINGIZER(x)
#include HEADER(SOURCE)
int main(void)
{
return(function());
}
$ cat f1.c
static int function(void)
{
return(1);
}
$ cat f2.c
static int function(void)
{
return(2);
}
$
Then I can compile like this:
$ gcc -DSOURCE=f1.c -o so1 so.c
$ gcc -DSOURCE=f2.c -o so2 so.c
Note the use of the stringize operator and the double-macro dance - this is a standard idiom for the Standard C Preprocessor. It allows me to avoid putting quotes in the C compiler command line; think how much harder it would be to use if you had to write:
$ gxx -DSOURCE='"f1.c"' -o so1.c
The results of running so1 and so2 were:
$ ./so1; echo $?
1
$ ./so2; echo $?
2
$
This shows an alternative way to achieve the desired result without any #ifdef
lines.
if you must insist on using C, you can use function pointers, but I would advice you to use C++ and polymorphism, this will get you of your troubles : )