Препроцессор ## Оператор и переменная - PullRequest
0 голосов
/ 11 марта 2019

Есть ли способ «сгенерировать» имя функции, используя оператор ## и значение переменной.Например:

#define FUN_I(fun, fun_id)  fun##fun_id
#define FUN(fun, fun_id)    RECV_CB_FUN_I(fun, fun_id)

int foo0(int x) {
    // do something
}
int main()
{
   int i = 0;
   FUN(foo,i)(1);
}

Макрос FUN создает fooi.Есть ли способ получить foo0 каким-то образом, или я должен использовать фактическое число 0 в этом случае, например, FUN(foo, 0)(1);

Cheers

Ответы [ 3 ]

3 голосов
/ 11 марта 2019

Вы должны использовать фактический 0 (или другой макрос).Расширение макроса обрабатывается препроцессором C во время компиляции.Он ничего не знает о значениях переменных во время выполнения.

2 голосов
/ 11 марта 2019

Как уже говорилось, расширение макроса выполняется во время компиляции, поэтому имя функции не будет известно во время выполнения.

Более целесообразно использовать указатели на функции и массив к ним.

Пример:

typedef int (*TFoo)(int);

int foo1(int x)
{
    printf("from foo1: x = %d\n", x);
    return 0;
}

int foo2(int x)
{
    printf("from foo2: x = %d\n", x);
    return 0;
}

TFoo foos[2] = {foo1, foo2};
#define foo(i, x) foos[i](x)

Вот и все. Надеюсь, это поможет

1 голос
/ 11 марта 2019

Предварительная обработка 'c' - это процесс замены макросов текстом из их определений.некоторые операции, такие как ##, позволяют добавлять свой аргумент в виде текста в определения.Итак, все сделано еще до начала компиляции.

В результате в вашем случае FUN(fun,i) будет подставлено в виде текста и формы funi.Единственный ограниченный способ создания имен функций, которые вы хотите, - это использовать реальные текстовые значения или другие макросы.Вот 2 примера, которые будут работать с предварительной обработкой:

FUN(fun, 0)(1);

или

#define I 0
FUN(fun, I)(1);

В последнем случае I - это сам макрос, поэтому он также работает.(всегда полезно называть имя макроса заглавными буквами).

...