In GNU C, a macro can accept a variable number of arguments, just like a function, such as:
12 |
#define pr_debug(fmt,arg...) \ printk(KERN_DEBUG fmt, ##arg) |
Passing variable parameter tables with variable-parameter macros (Variadic macros)
You may be familiar with the use of variable parameter tables in functions such as:
1 |
void printf ( const char * format, ...); |
Until recently, a mutable parameter table could only be applied to a real function and could not be used in a macro.
The C99 compiler standard has finally changed this board , which allows you to define variable parameter macros (Variadic macros) so that you can use a macro that has a parameter table that can be changed. Variable-parameter macros look like this :(vs2013 support)
1 |
#define debug(...) printf(__VA_ARGS__) |
The default number represents a table of parameters that can be changed. Use the reserved name __va_args__ to pass parameters to the macro. When the macro's call is expanded, the actual parameters are passed to printf (). For example:
The processor replaces the macro call with the following:
Because Debug () is a variable parameter macro, you can pass a different number of arguments in each call:
1 |
debug( "test" ); // 一个参数 |
Variable parameter macros are not officially supported by Ansi/iso C + +. Therefore, you should check your compiler to see if it supports this technology.
Easily print debug information with GCC and C99 variable-parameter macros
The variable-parameter macro definition provided by GCC preprocessing is really useful:
123456 |
#ifdef DEBUG #define dbgprint(format,args...) \ fprintf (stderr, format, ##args) #else #define dbgprint(format,args...) #endif |
Once this is defined, Dbgprint can be used in the code, such as Dbgprint ("%s", __file__);
Here's how to C99:
1 |
#define dgbmsg(fmt,...) printf(fmt,__VA_ARGS__) |
The new C99 specification supports variable-parameter macros
The specific use is as follows:
The following is the program code:
12345678 |
#include <stdarg.h> #include <stdio.h> #define LOGSTRINGS(fm, ...) printf(fm,__VA_ARGS__) int main() { LOGSTRINGS( "hello, %d " , 10); return 0; } |
But now it seems that only GCC supports it.
The ' # # ' operation in a variable-parameter macro shows a macro with variable parameters (Macros with a Variable number of Arguments)
In the 1999 version of the ISO C standard, macros can be defined as functions with variable parameters. The syntax of a macro is similar to the syntax of a function. Here's an example:
1 |
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__) |
Here, ' ... ' refers to variable parameters. When such a macro is called, it (here means ' ... ') is represented as 0 or more symbols, including the comma inside, until the end of the right parenthesis. When called, in the macro body, those symbol sequence sets will replace the __va_args__ identifier inside. For more information, refer to the CPP manual.
GCC always supports complex macros, and it uses a different syntax so that you can give a variable parameter a name, just like any other parameter. For example, the following example:
1 |
#define debug(format, args...) fprintf (stderr, format, args) |
This is exactly the same as the macro example defined by the ISO C above, but it is more readable and easier to describe.
GNU CPP also has two more complex macro extensions that support the definition format of the above two formats.
In standard C, you can't omit mutable arguments, but you can pass an empty argument to it. For example, the following macro call is illegal in ISO C because there is no comma behind the string:
Debug ("A message")
GNU CPP allows you to completely ignore mutable parameters in this case. In the example above, the compiler still has a problem (complain), because after the macro expands, there will be an extra comma behind the string.
To solve this problem, Cpp uses a special ' # # ' operation. The writing format is:
1 |
#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__) |
Here, if the variable parameter is ignored or empty, the' # # ' operation causes the preprocessor (preprocessor) to remove the comma in front of it . If you do provide some mutable parameters when you call the macro, the GNU CPP will work as well, and it will put the mutable parameters behind the comma. Like other pasted macro parameters, these parameters are not an extension of the macro.
# #还可以起到替换作用
Such as:
1 |
#define FUN(IName) IName##_ptr |
This will turn the iname into an actual number .
How to write macros with variable number of parameters
A popular technique is to define and invoke macros in a separate bracketed "parameter", which becomes the entire argument list for functions like printf () when the macro expands.
12 |
#define DEBUG(args) (printf("DEBUG: "), printf args) if (n != 0) DEBUG(( "n is %d\n" , n)); |
The obvious flaw is that callers must remember to use a pair of extra parentheses.
GCC has an extension that allows a function-type macro to accept a variable number of arguments. But that's not the norm. Another possible solution is to use multiple macros (DEBUG1, DEBUG2, etc.) depending on the number of arguments, or use commas to play a trick like this:
123 |
#define DEBUG(args) (printf("DEBUG: "), printf(args)) #define _ , DEBUG( "i = %d" _ i); |
C99 introduces formal support for functional macros with variable number of parameters. Add a symbol at the end of the macro ' prototype ' ... (as in a variable function definition), the pseudo-macro __va_args__ in the macro definition is replaced with a mutable parameter in the call.
Finally, you can always use real functions to accept well-defined mutable parameters
If you need to replace a macro, use a function and a non-functional macro, such as #define printf myprintf
Transferred from: http://www.cnblogs.com/alexshi/archive/2012/03/09/2388453.html
C Language # # __VA_ARGS__ macro