How to Write macro with variable number of parameters

Source: Internet
Author: User
Tags variadic

In gnu c, macros can accept variable parameters, just like functions, such:
# Define pr_debug (fmt, arg ...)/
Printk (KERN_DEBUG fmt, # arg)

Use variadic macros to transmit Variable Parameter tables
You may be familiar with Using Variable Parameter tables in functions, such:

Void printf (const char * format ,...);

Until recently, variable parameter tables can only be applied to real functions and cannot be used in macros.

The C99 compiler standard has finally changed this situation. It allows you to define variadic macros so that you can use macros with Variable Parameter tables. Variable Parameter macros look like the following:

# Define debug (...) Printf (_ VA_ARGS __)

The default number indicates a variable parameter table. Use the reserved name_va_args _ to pass the parameter to the macro. When macro calls are expanded, the actual parameters are passedPrintf (). For example:

Debug ("Y = % d/n", y );

The processor will replace macro calls:

Printf ("Y = % d/n", y );

BecauseDebug ()Is a variable parameter macro, you can pass different numbers of parameters in each call:

Debug ("test"); // A PARAMETER

Variable Parameter macros are not officially supported by ANSI/iso c ++. Therefore, you should check your compiler to see if it supports this technology.

 

You can use variable parameter macros of GCC and C99 to conveniently print debugging information.

The Variable Parameter macro definition provided by gcc preprocessing is really useful:

#ifdef DEBUG#define dbgprint(format,args...) /fprintf(stderr, format, ##args)#else#define dbgprint(format,args...)#endif

After this definition, dbuplint can be used in the Code, for example, dbuplint ("aaa % s", _ FILE __);. I think this function is Cool: em11:

Below is the C99 method:

#define dgbmsg(fmt,...) /             printf(fmt,__VA_ARGS__)

The new C99 specification supports macros with variable parameters.

The specific usage is as follows:

The following is the program code:

# 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 is supported.

'##' In the macro of variable parameters

Macro with Variable parameters (Macros with a Variable Number of Arguments)

In iso c 1999, macros can be defined with variable parameters like functions. Macro syntax is similar to function syntax. The following is an example:

# Define debug (format,...) fprintf (stderr, format, _ VA_ARGS __)

Here ,'... 'Indicates a variable parameter. When this type of macro is called, it (here '... ') Is expressed as zero or multiple symbols, including commas (,) until the end of the right arc. When called, in macro body, the symbolic sequence set replaces the _ VA_ARGS _ identifier. For more information, see the CPP manual.

GCC always supports complex macros. It uses a different syntax so that you can give variable parameters a name, just like other parameters. For example:

# Define debug (format, args...) fprintf (stderr, format, args)

This is exactly the same as the macro example defined in iso c above, but it is more readable and easy to describe.

Gnu cpp has two more complex macro extensions that support the preceding two formats.

In standard C, you cannot omit variable parameters, but you can pass it an empty parameter. For example, the following macro call is invalid in iso c because the string is not followed by a comma:

Debug ("A message ")

In this case, gnu cpp allows you to ignore variable parameters completely. In the above example, the compiler still has a problem (complain), because after the macro is expanded, there will be an extra comma behind the strings.

To solve this problem, CPP uses a special '#' operation. The writing format is:

# Define debug (format,...) fprintf (stderr, format, ##_ VA_ARGS __)

Here, if the variable parameter is ignored or empty, the '#' operation will remove the comma before the preprocessor. If you provide some variable parameters during macro calls, gnu cpp will also work normally, and it will put these variable parameters behind the comma. Like other pasted macro parameters, these parameters are not macro extensions.

How to Write macro with variable number of parameters

A popular technique is to define and call a macro using a single ''parameter enclosed by arc. When a macro is extended, the parameter becomes like printf () the entire parameter list of such a function.

    #define DEBUG(args) (printf("DEBUG: "), printf args)    if(n != 0) DEBUG(("n is %d/n", n));

The obvious defect is that the caller must remember to use an additional arc.

Gcc has an extension that allows function macros to accept variable number parameters. But this is not a standard. Another possible solution is to use multiple macros (DEBUG1, DEBUG2, etc.) based on the number of parameters, or use commas to play such a trick:

    #define DEBUG(args) (printf("DEBUG: "), printf(args))    #define _ ,    DEBUG("i = %d" _ i);

C99 introduces the formal support for function macros with variable numbers of parameters. Add the symbol at the end of the macro ''prototype... (like in the Variable Parameter Function Definition), the pseudo macro _ VA_ARGS _ in the macro definition will be replaced with the variable parameter in the call.

Finally, you can always use real functions to accept clearly defined variable parameters.

If you need to replace the macro, use a function and a non-FUNCTION macro, such as # define printf myprintf.

From: http://blog.csdn.net/aobai219/archive/2010/12/22/6092292.aspx Compile Variable Parameter debugging information (you can specify the position of debugging information in the source code)

 

The ansi c standard has several predefined macros (which are also commonly used ):

_ LINE __: Insert the current source code LINE number into the source code;

_ FILE __: insert the name of the current source FILE into the source FILE;

_ DATE __: Insert the current compilation DATE into the source file

_ TIME __: Insert the current compilation TIME into the source file;

_ Stdc __: when the program strictly follows the ansi c standard, the ID is assigned 1;

_ Cplusplus: This identifier is defined when a C ++ program is compiled.

The compiler automatically replaces these macros with the corresponding content during source code compilation.

 

Debug_printf can be written as follows:

Debug_printf (format ,...) printf ("file:" _ file _ ", line: % d:" format, _ line __,#__ va_args __)

All debug_printf information will be output in this way:

File: XXX, line: XXX ,.......

 

The reference code is as follows:

The output information is as follows:

In gnu c, macros can accept variable parameters, just like functions, such:
# Define pr_debug (FMT, Arg ...)/
Printk (kern_debug FMT, # Arg)

Use variadic macros to transmit Variable Parameter tables
You may be familiar with Using Variable Parameter tables in functions, such:

Void printf (const char * format ,...);

Until recently, variable parameter tables can only be applied to real functions and cannot be used in macros.

The c99 compiler standard has finally changed this situation. It allows you to define variadic macros so that you can use macros with Variable Parameter tables. Variable Parameter macros look like the following:

# Define debug (...) Printf (_ va_args __)

The default number indicates a variable parameter table. Use the reserved name_va_args _ to pass the parameter to the macro. When macro calls are expanded, the actual parameters are passedPrintf (). For example:

Debug ("y = % d/N", y );

The processor will replace macro calls:

Printf ("y = % d/N", y );

BecauseDebug ()Is a variable parameter macro, you can pass different numbers of parameters in each call:

Debug ("test"); // A PARAMETER

Variable Parameter macros are not officially supported by ANSI/iso c ++. Therefore, you should check your compiler to see if it supports this technology.

 

You can use variable parameter macros of GCC and C99 to conveniently print debugging information.

The Variable Parameter macro definition provided by gcc preprocessing is really useful:

#ifdef DEBUG#define dbgprint(format,args...) /fprintf(stderr, format, ##args)#else#define dbgprint(format,args...)#endif

After this definition, dbuplint can be used in the Code, for example, dbuplint ("aaa % s", _ FILE __);. I think this function is Cool: em11:

Below is the C99 method:

#define dgbmsg(fmt,...) /             printf(fmt,__VA_ARGS__)

The new C99 specification supports macros with variable parameters.

The specific usage is as follows:

The following is the program code:

# 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 is supported.

'##' In the macro of variable parameters

Macro with Variable parameters (Macros with a Variable Number of Arguments)

In iso c 1999, macros can be defined with variable parameters like functions. Macro syntax is similar to function syntax. The following is an example:

# Define debug (format,...) fprintf (stderr, format, _ VA_ARGS __)

Here ,'... 'Indicates a variable parameter. When this type of macro is called, it (here '... ') Is expressed as zero or multiple symbols, including commas (,) until the end of the right arc. When called, in macro body, the symbolic sequence set replaces the _ VA_ARGS _ identifier. For more information, see the CPP manual.

GCC always supports complex macros. It uses a different syntax so that you can give variable parameters a name, just like other parameters. For example:

# Define debug (format, args...) fprintf (stderr, format, args)

This is exactly the same as the macro example defined in iso c above, but it is more readable and easy to describe.

Gnu cpp has two more complex macro extensions that support the preceding two formats.

In standard C, you cannot omit variable parameters, but you can pass it an empty parameter. For example, the following macro call is invalid in iso c because the string is not followed by a comma:

Debug ("A message ")

In this case, gnu cpp allows you to ignore variable parameters completely. In the above example, the compiler still has a problem (complain), because after the macro is expanded, there will be an extra comma behind the strings.

To solve this problem, CPP uses a special '#' operation. The writing format is:

# Define debug (format,...) fprintf (stderr, format, ##_ VA_ARGS __)

Here, if the variable parameter is ignored or empty, the '#' operation will remove the comma before the Preprocessor. If you provide some variable parameters during macro calls, gnu cpp will also work normally, and it will put these variable parameters behind the comma. Like other pasted macro parameters, these parameters are not macro extensions.

How to Write macro with variable number of parameters

A popular technique is to define and call a macro using a single ''parameter enclosed by arc. When a macro is extended, the parameter becomes like printf () the entire parameter list of such a function.

    #define DEBUG(args) (printf("DEBUG: "), printf args)    if(n != 0) DEBUG(("n is %d/n", n));

The obvious defect is that the caller must remember to use an additional arc.

GCC has an extension that allows function macros to accept variable number parameters. But this is not a standard. Another possible solution is to use multiple macros (debug1, debug2, etc.) based on the number of parameters, or use commas to play such a trick:

    #define DEBUG(args) (printf("DEBUG: "), printf(args))    #define _ ,    DEBUG("i = %d" _ i);

C99 introduces the formal support for function macros with variable numbers of parameters. Add the symbol at the end of the macro ''prototype... (like in the Variable Parameter Function Definition), the pseudo macro _ va_args _ in the macro definition will be replaced with the variable parameter in the call.

Finally, you can always use real functions to accept clearly defined variable parameters.

If you need to replace the macro, use a function and a non-FUNCTION macro, such as # define printf myprintf.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.