In-depth analysis of the implementation of variable length parameter functions

Source: Internet
Author: User

What is a variable length parameter?

A function with variable length parameters is a function that accepts variable parameters. For example, we are all very familiar

Printf, scanf, etc.

2: How to Implement the variable length parameter?

First, let's look at the following example:

# Include <stdio. h>
# Include <stdarg. h>
# Include <string. h>

Void demo (char * MSG ,...)
{
Va_list argp;
Int arg_number = 0;
Char * para = MSG;
Va_start (argp, MSG );
While (1)
{
If (strcmp (para, "/0 ")! = 0)
{
Arg_number ++;
Printf ("parameter % d is: % s/n", arg_number, para );

}
Else
Break;
Para = va_arg (argp, char *);
}
Va_end (argp );
}
Int main ()
{
Demo ("hello", "world", "/0 ");
System ("pause ");
Return 0;
}

To implement such a function, use va_list, va_start, va_arg, and va_end internally.

Macro in stdarg. h.

Va_list defines a Data Structure for saving function parameters.

Va_start (argp, MSG) points argp to the first variable parameter, and MSG is the final parameter.

The meaning of the final parameter is that all subsequent parameters are variable parameters. If the following function declaration is available

Void demo (char * msg1, char * msg2 ,...)

The final parameter here is msg2.

Va_arg (argp, char *) returns the value of the current parameter, type: char *, and points argp to the next variable-length parameter.

Number. From this step, we can see that we can use va_start and va_arg to traverse all variable-length parameters.

Va_end: Set the argp value to 0.

Let's take a look at the implementation methods of the above Macros in Visual C ++. NET 2003. First, implement va_list.

# Ifdef _ m_alpha
Typedef struct {
Char * a0;/* pointer to first homed integer argument */
Int offset;/* byte offset of next parameter */
} Va_list;
# Else
Typedef char * va_list;
# Endif

We can see that va_list is actually a machine type macro, except for Alpha machines, other machine classes

Type is defined as a char type pointer variable. The reason why it is defined as char * is that it can be used

The address is used to traverse parameters by byte.

We can see from the above that the implementation of these macros is related to machines. The following is a commonly used ix86 machine macro.

Related definitions.

# Elif defined (_ m_ix86)

# DEFINE _ intsizeof (N) (sizeof (n) + sizeof (INT)-1 )&~ (Sizeof (INT)-1 ))

# Define va_start (AP, V) (AP = (va_list) _ addressof (v) + _ intsizeof (v ))
# Define va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t )))
# Define va_end (AP) (AP = (va_list) 0)

# Ifdef _ cplusplus
# DEFINE _ addressof (V) (& reinterpret_cast <const char &> (v ))
# Else
# DEFINE _ addressof (V) (& (v ))
# Endif

First look at _ intsizeof (N)

We know that for ix86, sizeof (INT) must be an integer multiple of 4, SO ~ (Sizeof (INT)-1) The value must be

The right side [sizeof (N)-1]/2 digits is 0. The macro ensures that the right side [sizeof (N)-1]/2 digits are 0, and the remaining positions are

It is 1, so the value of _ intsizeof (n) can only be 2, 4, 8, 16,... and so on. In fact, it achieves byte alignment.

# Define va_start (AP, V) (AP = (va_list) _ addressof (v) + _ intsizeof (v ))

So the role of va_start (AP, v) is very clear, _ addressof (v) defines the starting address of V, _ intsizeof (v) defines the V

Memory occupied, so the AP points to the starting address of the parameter after v.

# Define va_arg (AP, t) (* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t )))

AP + = _ intsizeof (t) enables the AP to point to the address of the next Parameter

(* (T *) (AP + = _ intsizeof (t)-_ intsizeof (t) returns the value of the current T type parameter.

# Define va_end (AP) (AP = (va_list) 0)

Set the value of the AP variable to 0.

Through the above analysis, we once again confirmed our interpretation of Variable Parameter implementation.

Therefore, we can summarize the general implementation methods of variable-length parameter functions:

1: declare the prototype, such as void demo (char * MSG,...). Note that the prototype Declaration of the variable length parameter must contain at least

A definite parameter.

2: Use va_list to define the data structure for saving function parameters. It can be understood as a pointer variable (which will be explained later ).

3: Use va_start to point the variable defined in the previous step to the first variable parameter.

4: Use va_arg to traverse all variable parameters.

5: Use va_end to set the address value held by the pointer variable to 0.

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.