2013-11-07 14 views
0

У меня есть файл C с определением функции.C множественные определения функций с использованием препроцессора

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

    #ifdef SOMEFEATURE 
     do_one_way; 
    #else 
     do_another_way; 
    #endif 

    do_something_else; 
} 

Если я определяю SOMEFEATURE в заголовке или в Makefile я получаю одну версию, если я не получаю другую версию. Мне нужны две версии. Я понимаю, что могу копировать и вставлять код и определять/деформировать символ, но это кажется беспорядочным. Есть ли способ, которым я могу определить обе функции без дублирования кода?

+1

Может быть, это очевидно для других, но я не понимаю ваш вопрос. «Мне нужны две версии»? Две версии чего? У вас уже нет двух версий этой функции? –

+0

Я хочу определить как myfunction_withfeature(), так и myfunction_withoutfeature(). Эти функции очень похожи и отличаются только частями, окруженными макросами препроцессора. Я хочу сохранить один экземпляр кода, но обе функции скомпилированы в исполняемый файл. – user2965755

ответ

1

Ну, вы можете скомпилировать код дважды:

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

, а затем связать эти objectfiles. Имейте в виду, что вам нужно будет убедиться, что другие функции, не имеющие «двух версий», будут дублированы, а компоновщику это не понравится. Поэтому вам нужно будет установить ifdefs вокруг них или убедиться, что ваш файл содержит только функции с «ifdef SOMEFEATURE».

В целом, я считаю, что это плохое дизайнерское решение, и следует избегать его, если это возможно.

+0

Да, это то, о чем я думал, но надеялся избежать этого, поскольку файл C имеет другие соответствующие функции. Любые предложения по достижению того же самого в более элегантной манере? – user2965755

2

Одна возможность поставить только функцию в отдельном файле, скажем 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"); 
    } 

А потом #include его в файле с другими функциями:

#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; 
    } 

Или вы можете делать ужасные вещи с макросами:

#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; 
    } 

Или сгенерируйте код для различных функций, используя скрипт.

0

@Thomas Padron-McCarth имеет правильный способ решения, если вы хотите использовать препроцессор, на мой взгляд. Если для этого все слишком сложно, тогда вам нужно переключиться на другую систему шаблонов или генерации кода. Я лично использовал perl-скрипты, которые выплескивают код C или C++, а затем есть Cog, который использует python для замены разделов кода на лету.

0

Вы могли:

  • Переместить общий код в подпрограмм (функций).

  • Pass флаг в качестве аргумента: например:

    myfunction_withfeature() { myfunction_common(true); }

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; 
} 
+0

Хотелось бы, чтобы это было так легко ;-) – user2965755

Смежные вопросы