0

I'm having trouble with macros in C. Is there any way to call and get the value of a parameter in macro to call a function?

The example code below generates an error:

#define order(i) fruits_i##_banana()

void fruits_1_banana()
{
    printf("Order banana\n");
}

int main()
{
   int a = 1;
   order(a);
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Son
  • 3
  • 2
  • 1
    There is a literal replacement and the preprocessor doesn't translate `a` to 1, you can use an array of pointers to functions. – David Ranieri Nov 03 '21 at 06:20
  • 2
    Do not change the question when there is an answer. – David Ranieri Nov 03 '21 at 06:37
  • Thank you very much, could you mind telling more clearly how to use array of pointers to function in macro??? – Son Nov 03 '21 at 06:38
  • Sorry because the previous question is so confusing, so that i update a little bit the information that can understand more about my situation – Son Nov 03 '21 at 06:40
  • You have an example here: https://stackoverflow.com/a/37394374/1606345 of course you don't need to reverse, just use the prototypes and the array definition and you are done. – David Ranieri Nov 03 '21 at 06:50
  • Macros cannot be used for run-time purposes, simple as that. `a` is not an integer constant and therefore can't be used in this manner. There is no way to fix the code, consider a different solution to whatever problem you are trying to solve with this. – Lundin Nov 03 '21 at 08:37
  • Even though you've gotten a valid answer, it would probably be a good idea to avoid this kind of code generation if you can. It complicates your program and makes static analysis and debugging much more difficult. – einpoklum Nov 03 '21 at 13:19
  • Thanks all of you guy a lot for your help – Son Nov 03 '21 at 13:19

1 Answers1

2

You need to use ## before and after i.

#define order( i ) fruits_##i##_banana()

void fruits_1_banana()
{
    printf("Order banana\n");
}

int main()
{
   order(1);
}

Note that you cannot pass a to order because macro expansion doesn't take the value of a variable, it just uses the variable name as it is.

References: https://learn.microsoft.com/en-us/cpp/preprocessor/token-pasting-operator-hash-hash?view=msvc-160

Instead, you can use an array of function pointers:

#include <stdio.h>

static void fruits_0_banana(void)
{
    printf("Order banana 0\n");
}

static void fruits_1_banana(void)
{
    printf("Order banana 1\n");
}

static void (*order[])(void) = {
    fruits_0_banana, // Or NULL if you don't need it
    fruits_1_banana,
    // ...
};

int main(void)
{
    int a = 1;

    order[a]();
    return 0;
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
  • Thank you very much, i updated my code again but still get the error , because the macro not understand the value a is 1 :( – Son Nov 03 '21 at 06:32
  • Yes, you cannot pass `a` to `order`. – kiner_shah Nov 03 '21 at 06:33
  • so what i need to do so the macro can understand the value ? please help :( – Son Nov 03 '21 at 06:36
  • 1
    @Son, you need to update the question with your exact requirements, why do you need to pass a variable to a macro which will call the respective function? I think you may need to follow DavidRanieri's suggestion of using function pointers ([See this](https://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work)) – kiner_shah Nov 03 '21 at 06:40
  • i really appreciate for your help – Son Nov 03 '21 at 06:42
  • 1
    You can not, preprocessor doesn't work at runtime but at compile time, and the value of `a` is unknown at this stage, and even knowing the value (i.e using an `enum`) there is a literal replacement. Read about pointers to function, you can achieve what you want using `order()[1];` – David Ranieri Nov 03 '21 at 06:43
  • Sorry, you want `order[1]()` not `order()[1]` – David Ranieri Nov 03 '21 at 06:51
  • Okay i will give it a shoot – Son Nov 03 '21 at 06:53
  • @Son, give me half an hour and I provide an example in this answer (I'm on the mobile) – David Ranieri Nov 03 '21 at 06:59
  • @David I appreciate your help so much. – Son Nov 03 '21 at 07:03
  • 1
    Since it seems that @kiner_shah agrees with the use of function pointers, you have an edit, please, accept the answer if it was useful ;) – David Ranieri Nov 03 '21 at 07:30
  • Thank you a lot – Son Nov 03 '21 at 13:20