#Parameters used in define #, ##__ VA_ARGS__ And##__ VA_ARGS__

Keywords: C

#Converts macro parameters to strings at precompile time

#define PRINT_MACRO_HELPER(x) #x
#define PRINT_MACRO(x) PRINT_MACRO_HELPER(x)
#define PRINT_ANOTHER_MACRO(x) #x"="PRINT_MACRO_HELPER(x)
char *str=PRINT_MACRO_HELPER(1235982536);
char *str2=PRINT_MACRO(i);
char *str3=PRINT_ANOTHER_MACRO(i);
printf("the string of str is %s,the string of str2 is %s ,the string of str3 is %s\n",str,str2,str3);
Output:
the string of str is 1235982536,the string of str2 is i,the string of str3 is i=i

Macro connector##
It is used to connect two tokens in the macro definition with parameters to form a new substring; But it cannot be the first or last substring. The so-called token refers to the smallest syntax unit that the compiler can recognize. However, "##" cannot be arbitrarily bonded with any characters. It must be a legal C language identifier. The "#" or "##" preprocessing operator can appear at most once in a single macro definition. If you do not specify the calculation order related to the "#" or "##" preprocessing operator, a problem occurs. To avoid this problem, only one of these operators can be used in a single macro definition (that is, one "#" or one "##" or none). Try not to use "#" and "##" unless it is very necessary.

For example: the macro is defined as #define XNAME(n) x##n and the code is XNAME(4). When the macro finds that XNAME(4) matches XNAME(n) during precompiling, make n 4, then change the content of N on the right to 4, and then replace the whole XNAME(4) with x##n, that is, x4, so the final result is that XNAME(4) becomes X4. As shown in the following example:

#include <stdio.h>
#define XNAME(n) x##n
#define PRINT_XN(n) printf("x" #n " = %d\n", x##n);
int main(void)
{
    int XNAME(1) = 14; // becomes int x1 = 14;
    int XNAME(2) = 20; // becomes int x2 = 20;
    PRINT_XN(1);       // becomes printf("x1 = %d\n", x1);
    PRINT_XN(2);       // becomes printf("x2 = %d\n", x2);
    return 0;
}

Variable parameter macro

In GNU C, starting from C99, macros can accept variable parameters, just like variable parameter functions. Like functions, macros use three points... To represent variable parameters

VA_ARGS macro
VA_ARGS macro is used to represent the contents of variable parameters. In short, it is to copy the contents of... In the macro on the left to the right__ VA_ARGS__ Location. The following example code:

#include <stdio.h>
#define debug(...) printf(__VA_ARGS__)
int main(void)
{
    int year = 2018;
    debug("this year is %d\n", year); //The effect is the same as printf ("this year is% d \ n", year);
}

Variable parameter nickname
In addition, through some syntax, you can give a name to the variable parameter instead of using__ VA_ARGS__ , args in the following example:

#include <stdio.h>
#define debug(format, args...) printf(format, args)
int main(void)
{
    int year = 2018;
    debug("this year is %d\n", year);  //The effect is the same as printf ("this year is% d \ n", year);
}

No parameter input
Different from the variable parameter function, the variable parameter in the variable parameter macro must have at least one parameter passed in, otherwise an error will be reported. In order to solve this problem, a special "##" operation is required. If the variable parameter is ignored or empty, the "##" operation will make the preprocessor remove the comma in front of it. The following example is shown

#include <stdio.h>
#define debug(format, args...) printf(format, ##args)
int main(void)
{
    int year = 2018;
    debug("hello, world");  //Only format parameter, no args variable parameter
}

Posted by fangorn on Fri, 03 Sep 2021 21:23:20 -0700