2009-12-23 2 views
7

У меня есть следующий кодМакро и функция с таким же именем

#define myfunc(a,b) myfunc(do_a(a), do_b(b)) 

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 

Я хочу предварительно процессор расширить функции MyFunc только при вызове. Необходимый код после предварительной обработки выглядит следующим образом:

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
int main() 
{ 
    int x = 6, y = 7; 
    myfunc(do_a(x),do_b(y)); 

    return 0; 
} 

Проблема в том, что определение функции расширяется также как этот

void myfunc(do_a(int a), do_b(int b)) 
{ 
    do_blah(a,b); 
} 

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

Примечание: Пожалуйста, не говорите мне, чтобы переименовать макрос или функцию имен: D

Update1: Спасибо за помощь. Но я могу изменить определение макроса, я не могу изменить его положение, и я не могу изменить реализацию функции.

ответ

15

() Используйте, чтобы остановить препроцессор от расширения определения функции:

#include <stdio.h> 

#define myfunc(a, b) myfunc(do_a(a), do_b(b)) 
/* if you have a preprocessor that may be non-standard 
* and enter a loop for the previous definition, define 
* myfunc with an extra set of parenthesis: 
#define myfunc(a, b) (myfunc)(do_a(a), do_b(b)) 
******** */ 

int (myfunc)(int a, int b) /* myfunc does not get expanded here */ 
{ 
    printf("a=%d; b=%d\n", a, b); 
    return 0; 
} 

int do_a(int a) 
{ 
    return a * 2; 
} 

int do_b(int b) 
{ 
    return b - 5; 
} 

int main(void) 
{ 
    myfunc(4, 0); 
    return 0; 
} 
+0

Это работает :) спасибо – Yousf

+0

Я думаю, что некоторые препроцессоры могут отказаться от рекурсивного использования формы myfunc (xxx, xxx).Я бы сделал #define MyFunc (а, Ь) (MyFunc) (do_a (а), do_b (б)) Int (MyFunc) (Int А, внутр б) и с –

+2

Хорошая мысль, Тим, спасибо ! Но я думаю, что можно с уверенностью предположить, что препроцессор никогда не войдет в рекурсивный цикл (cf Standard 6.10.3.4/2 "... если какие-либо вложенные замены встречаются с именем заменяемого макроса, оно не заменяется ..."). – pmg

0

Определите макрос после определения функции.

В качестве альтернативы, использовать шаблон, как это:

#define myfunc_macro(a,b) myfunc(do_a(a), do_b(b)) 
#define myfunc(a,b) myfunc_macro(a,b) 

. 
. 

#undef myfunc 
void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 
#define myfunc(a,b) myfunc_macro(a,b) 

. 
. 

int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 
3

Определение макро после Согласно определению функции.

void myfunc(int a, int b) 
{ 
    do_blah(a,b); 
} 

#define myfunc(a,b) myfunc(do_a(a), do_b(b)) 

int main() 
{ 
    int x = 6, y = 7; 
    myfunc(x,y); 

    return 0; 
} 
8

Я вижу три возможных решения:

  • определяют макрос после определения функции.

  • определяют перед определением функции, do_a() и do_b() таким образом, что они возвращают свой аргумент, и переопределить их по вашему желанию после определения функции

  • выполнять do_a() и do_b() внутри функции:

    void myfunc(int a, int b) 
    { 
        do_blah(do_a(a),do_b(b)); 
    } 
    

У меня есть сильное предпочтение последнему.

0

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

+0

это унаследованный код .. меняется функция или имена макросов не вариант. – Yousf

+0

Просто невозможно, что вы можете изменить макрос, а не функцию. Просто невозможно, что вы можете скомпилировать файл, но не выбрать, какой файл компилировать. Ты говоришь мусор. –

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