0

What's happening in this macro? I understand that #test expand this parameter to the literal text. But what does pre; and test; do?

#define MACRO_FN(test, pre, repeat, size)    \
  do {                                     \
    printf("%s: ", #test);                 \
    for (int i = 0; i < repeat; i++) {     \
      pre;                                 \
      test;                                \
    }                                      \
  } while (0)

This is used like so

MACRO_FN(a_func(an_array, size),, var1, size);

What do the double commas mean here?

Gar
  • 305
  • 2
  • 9
  • 3
    Run the code through the preprocessor and look what the macro expands to. – Some programmer dude Nov 19 '18 at 12:36
  • 1
    To omit `pre;`- maybe? Did you check the pre-processed code? – Sourav Ghosh Nov 19 '18 at 12:37
  • I didn't think to check the output of the pre-processor, but I'll do that now – Gar Nov 19 '18 at 12:47
  • 2
    When invoking a preprocessor macro , "blank" is a valid argument; the call `MACRO_FN(a,,b,c)` means that `pre` will expand to blank – M.M Nov 19 '18 at 12:50
  • Could you show a [MCVE]? – Jabberwocky Nov 19 '18 at 12:54
  • 2
    Please note that macros like these should be avoided like the plague. – Lundin Nov 19 '18 at 12:55
  • @JackEvans: You are missing the closing bracket for the `for` loop, so I don't understand how this works. This is a rather terrible idea for a macro, btw, but whoever wrote it probably didn't realize you can pass two calls as a single parameter (using `MACRO_FN({test1();test2();}, var, 100);` or `MACRO_FN((test1(),test2()), var, 100);`). – vgru Nov 19 '18 at 13:24
  • Yes, this isn't my code, I am just trying to understand it. I have removed some parts of the macro – Gar Nov 19 '18 at 13:50
  • What is `repeat`. It's nowhere in the question. We need a **[mcve]**. – Jabberwocky Nov 19 '18 at 13:58
  • @JackEvans: I would presume the point of this is to repeat a function call several times, probably to measure execution time (e.g. a variant of [this](https://stackoverflow.com/q/39729876/69809)). So whoever wrote it presumably wanted to avoid the overhead of calling the function through a function pointer, which could make sense if the function is `static inline`. It it's not production code, the idea could generally pass for benchmarking, but this `pre` argument is complete nonsense IMHO. – vgru Nov 19 '18 at 14:09

2 Answers2

3

pre and test seem to be two functions. Based on how it is written, we can guess that pre is a function called before the test.

The double comma has no special meaning. It is just here because the second parameter (pre) was omitted.

Edit: As a side note that kind of macro "should be avoided like plague", as @Lundin put it.

Xaxetrov
  • 54
  • 4
3

Here is a minimal example:

#define repeat 5    // I added this, because 'repeat' is not mentionned in your question

#define MACRO_FN(test, pre, var1, size)    \
  do {                                     \
    printf("%s: ", #test);                 \
    for (int i = 0; i < repeat; i++) {     \
      pre;                                 \
      test;                                \
    }                                      \
  } while (0)

void foo()
{
}

void func(int a, int b)
{
}

int main()
{
  MACRO_FN(func(2, 3), foo(), var1, size);
}

Once preprocessed, the code is equivalent to this:

int main()
{
  printf("%s: ", "func(2,3)");
  for (int i = 0; i < 5; i++)
  {
    foo();
    func(2, 3);
  }
}

So that macro is a wrapper that prints the function name plus it's parameters as it is invoked with the macro and executes that function specified in the first parameter repeat times (whatever repeat is). If the second parameter is omitted, the function that has that name is simple not invoked before the function mentioned before as in the following example:

int main()
{
  MACRO_FN(func(2, 3),, var1, size);
}

Once preprocessed, the code is equivalent to this:

int main()
{
  printf("%s: ", "func(2,3)");
  for (int i = 0; i < 5; i++)
  {
    ;
    func(2, 3);
  }
}

Note:

I removed the do while(0) from the equivalent programs for brevity, read this SO article for more information:

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115