0

I have a C file with a function definition.

#ifdef SOMEFEATURE
    myfunction_withfeature()
#else
    myfunction_withoutfeature()
#endif
{
    do_something;

    #ifdef SOMEFEATURE
        do_one_way;
    #else
        do_another_way;
    #endif

    do_something_else;
}

If I define SOMEFEATURE in a header or in the Makefile I get one version, if not I get another version. What I need is two versions. I understand I can copy and paste the code and define/undefine the symbol but that seems messy. Is there a way I can have both functions defined without duplicating code?

2
  • 1
    Maybe it's obvious to others, but I don't understand your question. "What I need is two versions"? Two versions of what? Don't you already have two versions of this function? Commented Nov 7, 2013 at 16:51
  • I want to define both myfunction_withfeature() and myfunction_withoutfeature(). These functions are very similar and differ only the parts surrounded by preprocessor macros. I want to maintain one instance of the code but have both functions compiled into the executable. Commented Nov 7, 2013 at 16:59

5 Answers 5

2

One possibility is to put just the function in a separate file, let's say justmyfunction.c:

    #ifdef SOMEFEATURE
        void myfunction_withfeature()
    #else
        void myfunction_withoutfeature()
    #endif
    {
        printf("Always doing this.\n");

        #ifdef SOMEFEATURE
            printf("Doing it one way, with the feature.\n");
        #else
            printf("Doing it another way, without the feature.\n");
        #endif

        printf("Always doing this too.\n");
    }

And then #include it in the file with the other functions:

    #include <stdio.h>

    #include "justmyfunction.c"

    #define SOMEFEATURE

    #include "justmyfunction.c"

    int main(void) {
        printf("Doing it twice...\n");
        myfunction_withfeature();
        myfunction_withoutfeature();
        printf("Done.\n");
        return 0;
    }

Or you can do horrible things with macros:

    #include <stdio.h>

    #define DEFINE_MYFUNCTION(function_name, special_code)  \
        void function_name() \
    { \
        printf("Always doing this.\n"); \
     \
        special_code \
     \
        printf("Always doing this too.\n"); \
    }

    DEFINE_MYFUNCTION(myfunction_withfeature, printf("Doing it one way, with the feature.\n");)

    DEFINE_MYFUNCTION(myfunction_withoutfeature, printf("Doing it another way, without the feature.\n");)

    int main(void) {
        printf("Doing it twice...\n");
        myfunction_withfeature();
        myfunction_withoutfeature();
        printf("Done.\n");
        return 0;
    }

Or generate the code for the different functions, using a script.

Sign up to request clarification or add additional context in comments.

Comments

1

Well, you can compile your code twice with:

cc -DSOMEFEATURE x.c -o x1.o
cc -x.c -o x2.o

and then link those objectfiles. Keep in mind, that you will need to make sure that the other functions that do not have "two versions" will be duplicated and linker won't like it. So you will need to put ifdefs around them, or to make sure that your file contains only functions with "ifdef SOMEFEATURE".

In general, I think that this is a bad design decision and one should avoid it if possible.

1 Comment

Yeah, this is what I was thinking of doing but was hoping to avoid it as the C file has other relevant functions. Any suggestions to achieve the same thing in a more elegant manner?
0

@Thomas Padron-McCarth has the right way to deal if you want to just use the pre-processor, in my opinion. If things get too complicated for that, then you'll need to switch to some other kind of templating or code-generation system. I've personally used perl scripts that spit out C or C++ code, and then there's Cog, which uses python to replace sections of code on the fly.

Comments

0

You could:

  • Move common code into subroutines (functions).

  • Pass a flag as an argument: eg:

    myfunction_withfeature() { myfunction_common(true); }

Comments

0
my_function_withfeature()
{
    my_common_function(1);
}

my_function_withoutfeature()
{
    my_common_function(0);
}   

my_common_function(int feature)
{
    do_something;

    if (feature == 1) {
            do_one_way;
    }
    else {
            do_another_way;
    }       

    do_something_else;
}

1 Comment

I wish it were that easy ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.