Макрос и функция с тем же именем - PullRequest
9 голосов
/ 23 декабря 2009

У меня есть следующий код

#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: Спасибо за помощь. Но я могу только изменить определение макроса, я не могу изменить его положение и не могу изменить реализацию функции.

Ответы [ 5 ]

19 голосов
/ 23 декабря 2009

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

#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;
}
8 голосов
/ 23 декабря 2009

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

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

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

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

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

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

3 голосов
/ 23 декабря 2009

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

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;
}
0 голосов
/ 23 декабря 2009

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

0 голосов
/ 23 декабря 2009

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

Либо используйте шаблон, подобный следующему:

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