2

I have similar macros defined with just difference in them is number. e.g

#define Function_01_Call(param)  (FunctionName((int)01, param))
#define Function_02_Call(param)  (FunctionName((int)02, param))
#define Function_03_Call(param)  (FunctionName((int)03, param))
#define Function_04_Call(param)  (FunctionName((int)04, param))

I want to call function FunctionName using macros Function_XX_Call. How can I use one string for macro with change in its numbers? I tried with

#define FUNCTION_CALL(num)   Function_num_Call

 int main()
 {
    char num;
    for(num = "01"; num<="04"; num++)
    {
       FUNCTION_CALL(num); //HOW TO PASS param HERE?
    }
  }

but how can I change the num dynamically during call as Variables cannot be used in macro. Also how to pass the param during call? Is there any way to use function pointers?

A.BHi
  • 33
  • 4

2 Answers2

4

how can I change the num dynamically

The best is to create callers and a lookup table. So completely ignore the whole processor stuff anything there is and move to runtime.

void function_call_01(int param) { Function_01_Call(param); }
void function_call_02(int param) { Function_02_Call(param); }
void function_call_03(int param) { Function_03_Call(param); }
void function_call_04(int param) { Function_04_Call(param); }

static void (*const function_calls[])(int) {
    function_call_01,
    function_call_02,
    function_call_03,
    function_call_04,
};
static const function_calls_cnt = sizeof(function_calls)/sizeof(*function_calls);

void function_call(size_t idx, int param) {
   assert(idx < function_calls_cnt);
   function_calls[idx](param);
}

int main() {
    for (size_t i = 0; i < function_calls_cnt; ++i) {
         function_call(i, 62);
    }
}

Preprocessor is static, it can't be changed after compilation. If you want anything to depend on something on runtime, you have to write it in runtime, not in preprocessor.

The function list and array definition could be "shortened" with FOREACH macros, like P99_SEQ or BOOST_PP_SEQ_FOR_EACH or similar.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • This is a valuable answer for having a single function call dispatching to four separate functions. However, OP's question seems to indicate that he/she is looking for the opposite: four function calls dispatching to a single function. But then again, the question is confusing... – Codo Apr 16 '21 at 08:15
  • I think the `FunctionName` in `#define Function_01_Call(param) (FunctionName((int)01, param))` was just a template, in real code the `FunctionName` is different for each macro. OP wants to implement `#define FUNCTION_CALL(num) Function_num_Call` dispatching. But sure - OP code could be just `FunctionName(i, param)`, because all 4 macros are the same... – KamilCuk Apr 16 '21 at 08:27
2

You can't!

Because the for loop will be executed at runtime, but the macros are expanded in the pre-processor phase, even before compiling. Obviously the value of num is unknown and can't be expanded in the macro at that time.

for(num = 1; num<=4; num++)
{
   FUNCTION_CALL(num); //HOW TO PASS param HERE?
}

Btw. You can't store a two character string in a char

You CAN do something like

#define __PASTE1(a,b,c)  __PASTE2(a,b,c)
#define __PASTE2(a,b,c)  a##b##c
#define FUNCTION_CALL(num,param)   __PASTE1(Function_,num,_Call)(param)

int main()
{
  FUNCTION_CALL(01); // Expands to Function_01_Call(param)
  FUNCTION_CALL(02);
  FUNCTION_CALL(03);
  FUNCTION_CALL(04); // Expands to Function_04_Call(param)
}
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Thanks for your response! Why two different macros __PASTE1 and __PASTE2 are used here? And what is significance of __ in macro? – A.BHi Apr 16 '21 at 08:04
  • @A.BHi The `__` has no special meaning for macros, I only used it to show that it's an *internal* macro. The `##` is the *concatenate token* in the preprocessor. In this case you don't need two __PASTE macros, it's only my habit to avoid other problems, like creating strings – jeb Apr 16 '21 at 08:12