Variable Parameter Function Definition and traps

Source: Internet
Author: User

I. Variable Parameter Function Definition Methods

 

Note: The original Article of this section is excerpted from the Internet. I have edited and expanded it as necessary. I am sorry and grateful for the fact that the original author has not found it.

 

In some cases, you can determine the number of parameters of the function as needed. Typical examples include the functions printf (), scanf (), and execl () called by the system. So how are they implemented? The C compiler usually provides a series of macros to handle this situation to shield the differences caused by different hardware platforms and increase program portability. These macros include va_start, va_arg, and va_end.

 

1. When the ANSI standard form is adopted, the prototype declaration of a function with a variable number of parameters is:

 

 

View plaincopy to clipboardprint?
  1. Type funcname (type para1, type para2 ,...)

Type funcname (type para1, type para2 ,...)

 

This form requires at least one common form parameter, and the ellipsis behind it does not mean to be omitted, but is part of the function prototype. Type is the type of function return values and formal parameters.

 

2. When the declaration method is compatible with UNIX System V, the prototype of the function with a variable number of parameters is:

 

 

View plaincopy to clipboardprint?
  1. Type funcname (va_alist)
  2. Va_dcl

Type funcname (va_alist) va_dcl

 

This form does not require any common form parameters. Type is the type of the function return value. Va_dcl is a detailed declaration of the parameter va_alist in the function prototype declaration. It is actually a macro definition. Different types are used for different hardware platforms, but a semicolon is included at the end. Therefore, you do not need to add a semicolon after va_dcl. Va_dcl must be provided in the Code as is. Va_alist can be provided as is or omitted in VC.

 

In addition, use the header file stdarg. the program written by H complies with the ANSI standard and can run on various operating systems and hardware. The header file varargs is used. H is only used for compatibility with previous programs. Therefore, we recommend that you use the former. The following describes how to process parameters in the previous method. The basic principles of the two methods are the same, but there are some minor differences in syntax form.

 

 

View plaincopy to clipboardprint?
  1. /* Get the pointer of the first variable parameter to arg_ptr.
  2. Last_firm_arg is the last fixed parameter in the function declaration.
  3. Macro parameters help the compiler locate the address of the first variable parameter because
  4. In the stack structure of the call, variable parameters are always after the variable parameters */
  5. Void va_start (va_list arg_ptr, last_firm_arg );
  6. /* Return the value of the current variable parameter specified by arg_ptr, and arg_ptr points to the next parameter.
  7. Cur_arg_type is the type of the current parameter, such as int
  8. Macro parameters help the compiler locate the address of the next Variable Parameter
  9. Note that the supported types are int and double. This is a trap and will be detailed below
  10. You can call this macro cyclically to obtain n parameter values */
  11. Cur_arg_type va_arg (va_list arg_ptr, cur_arg_type );
  12. /* Set arg_ptr to null */
  13. Void va_end (va_list arg_ptr );

/* Get the pointer of the first variable parameter to arg_ptr last_firm_arg, which is the last fixed parameter in the function declaration. This macro parameter facilitates the compiler to locate the address of the first variable parameter, in the stack structure of function calls, variable parameters always follow the variable parameters */void va_start (va_list arg_ptr, last_firm_arg ); /* return the value of the current variable parameter specified by arg_ptr, and arg_ptr points to the next parameter. cur_arg_type is the type of the current parameter, such as int, this macro parameter facilitates the compiler to locate the address of the next variable parameter. Note that the supported types are int and double, which is a trap, the following describes how to call this macro cyclically to obtain n parameter values */cur_arg_type va_arg (va_list arg_ptr, cur_arg_type);/* Set arg_ptr to null */void va_end (va_list arg_ptr );

 

Va_start points argp to the first optional parameter. Va_arg returns the current parameter in the parameter list and points argp to the next parameter in the parameter list. Va_end clears the argp pointer to null. The function can traverse these parameters multiple times, but all parameters must start with va_start and end with va_end.

 

When a caller calls a function with a variable number of parameters, the caller must specify the number of actual parameters in a certain way (note: in fact, the Data Type of each parameter (the number of bytes occupied) you also need to specify it in a certain way. For example, use the default type or use a fixed parameter to specify the type, printf () the first parameter -- formatted characters such as % d, % F, and % s are explicitly specified ), for example, if you set the last parameter to an empty string (execl () is called by the system),-1, or another method (the printf () function uses the first parameter, that is, the definition of the output format to determine the number of actual parameters ).

 

The following is a specific example. The Code follows the ANSI standard. Some comments are added to the code, so I will not explain them here. This example has been compiled and run properly in VC/Windows XP, CC/aix4.3.2.0, and GCC/suse7.3 environments.

 

Demonstrate how to use functions with variable parameter numbers in the ANSI standard format

 

 

View plaincopy to clipboardprint?
  1. # Include <stdio. h>;
  2. # Include <string. h>;
  3. # Include <stdarg. h>;
  4. /* The function prototype Declaration requires at least one definite parameter. Note the ellipsis in brackets */
  5. Int demo (char *,...);
  6. Void main (void)
  7. {
  8. Demo ("Demo", "this", "is", "A", "Demo! "," \ 0 ");
  9. }
  10. /* ANSI standard declaration method. The ellipsis in parentheses indicates an optional parameter */
  11. Int demo (char * MSG ,...)
  12. {
  13. Va_list argp;/* define the structure for saving function parameters */
  14. Int argno = 0;/* Number of record parameters */
  15. Char * para;/* stores the retrieved string parameters */
  16. /* Argp points to the first input optional parameter,
  17. MSG is the final parameter */
  18. Va_start (argp, MSG );
  19. While (1)
  20. {
  21. /* Retrieve the current parameter. The type is char *.*/
  22. Para = va_arg (argp, char *);
  23. /* Use an empty string to indicate the end of the parameter input */
  24. If (strcmp (para, "\ 0") = 0)
  25. Break;
  26. Printf ("parameter # % d is: % s \ n", argno, para );
  27. Argno ++;
  28. }
  29. Va_end (argp);/* Set argp to null */
  30. Return 0;
  31. }

# Include <stdio. h >;# include <string. h >;# include <stdarg. h>;/* The function prototype Declaration requires at least one definite parameter. Note the ellipsis in the brackets */INT demo (char *,...); void main (void) {demo ("Demo", "this", "is", "A", "Demo! "," \ 0 ");}/* ANSI standard declaration method. The ellipsis in parentheses indicates the optional parameter */INT demo (char * MSG ,...) {va_list argp;/* defines the structure of the stored function parameter */INT argno = 0;/* records the number of parameters */char * para; /* store the retrieved string parameter * // * argp points to the first optional parameter passed in. MSG is the final parameter */va_start (argp, MSG); While (1) {/* retrieve the current parameter, type: char *. */para = va_arg (argp, char *);/* use an empty string to indicate the end of the parameter input */If (strcmp (para, "\ 0") = 0) break; printf ("parameter # % d is: % s \ n", argno, para); argno ++;} va_end (argp ); /* Set argp to null */return 0 ;}

 

Ii. Variable Parameter type traps

 

The following code is incorrect and unexpected results are not displayed during the running:

 

 

View plaincopy to clipboardprint?
  1. Va_start (parg, plotno );
  2. Fvalue = va_arg (parg, float); // The type should be changed to double. Float is not supported.
  3. Va_end (parg );

Va_start (parg, plotno); fvalue = va_arg (parg, float); // The type should be changed to double. floatva_end (parg) is not supported );

 

The following lists types not supported by the va_arg (argp, type) macro:

 

-- Char, signed Char, and unsigned char
-- Short, unsigned short
-- Signed short, short int, signed short int, unsigned short int
-- Float

 

In C language, when a function without a prototype declaration is called, the caller will execute "Default argument promotions" for each parameter )". This rule also applies to variable parameter functions. For each actual parameter after the variable length parameter list exceeds the form parameter of the last type declaration, the above upgrade is also performed.

 

The improvement is as follows:
-- The actual parameter of float type will be upgraded to double
-- The actual parameters of char, short, and corresponding signed and unsigned types are upgraded to int
-- If int cannot store the original value, it is upgraded to unsigned Int.

 

Then, the caller passes the upgraded parameter to the caller.

 

Therefore, the Variable Parameter Function cannot receive the actual parameters of the above type.

 

C/C ++ has the following descriptions:

This trap is not mentioned in the C language programming chapter on the variable length parameter list. But there are rules for improving the default actual parameters:
In the absence of a function prototype, both the char and short types will be converted to the int type, and the float type will be converted to the double type.
-- C language programming version 2nd type conversion p36

This rule is also mentioned in other books:

It is clear that if a parameter is not declared, the compiler will have no information to perform standard type checks and conversions on it.
In this case, a char or short will be passed as an int, and float will be passed as a double.
These operations may not be expected by programmers.
Note: These are standard improvements inherited by C.
For parameters represented by ellipsis, the actual parameters always perform these enhancements before being passed (if they belong to the type to be upgraded), and the upgraded values are passed to the relevant functions. -- Translator's note
-- C ++ programming language version 3rd-Special Edition 7.6 P138

...... Float parameters are automatically converted to the double type. Parameters of the short or char type are automatically converted to the int type ......
-- C traps and defects: 4.4 form parameters and values of real participation in P73

There is a trap to avoid:
The 2nd parameters of the va_arg macro cannot be specified as char, short, or float.
Because char and short parameters are converted to the int type, float parameters are converted to the double type ......
For example, this is definitely not correct:
C = va_arg (AP, char );
Because we cannot pass a char parameter, if it is passed, it will be automatically converted to the int type. The above formula should be written:
C = va_arg (AP, INT );
-- C traps and defects p164

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.