Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C preprocessor macro multiple arguments

So I have this 'check' macro which takes two arguments :

#define check(reg, n) ((reg >> n) & 1U)

And I have this argument list :

#define TEST_ARGS 10, 1

The code :

check(TEST_ARGS);

Expected expansion :

((10 >> 1) & 1U)

Real expansion :

((10, 1 >> ) & 1U)

How do I define multiple arguments for "check" macro to get expected results?

Many Thanks.

like image 638
malidu Avatar asked Sep 02 '25 02:09

malidu


1 Answers

In top-level (not macro-replaced) input, macro invocations argument lists are parsed immediately, before the arguments are macro expanded. (This must be the case, because macro arguments used with # and ## macro operators are not expanded, and that's not known until the replacement body is examined.)

However, parameters in the replacement body are replaced with the respective arguments (which will have been macro-expanded if the parameter is not used with # or ##) before the replacement body is scanned for macros.

So you can achieve the effect you want by adding a level of indirection. However, you probably want to use a varargs macro, in case the invoker puts in an explicit comma:

#define CHECK(...) CHECK_(__VA_ARGS__)
#define CHECK_(reg, n) ((reg >> n) & 1U)

#define TEST_ARGS 10, 1
CHECK(TEST_ARGS)

Test:

$ $ gcc -x c -E - <<<'#define CHECK(...) CHECK_(__VA_ARGS__)
> #define CHECK_(reg, n) ((reg >> n) & 1U)
> 
> #define TEST_ARGS 10, 1
> CHECK(TEST_ARGS)'
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "<stdin>"




((10 >> 1) & 1U)
like image 119
rici Avatar answered Sep 04 '25 17:09

rici