Variable parameter functions in C + +

Source: Internet
Author: User
Tags function prototype

The best example of a variable parameter function: printf (); variable parameter

Included header files:

C Language: #include <stdarg.h>

header file for variable parameters in C + +: #include <cstdarg> it is actually a variable header file containing the C language stdarg.h

Imagine if we wanted to define a function, before we called (before the run-time) I didn't know exactly what I was going to call a few arguments, and I don't know what kind of arguments they are, for example, we want to define a function:
int max (int n, ...);
The maximum value used to return a string of arbitrary length input parameters, such as calling
Max (3, 10, 20, 30) can return (n=3) The maximum value of the number of 10,20,30 30.
You can also accept input from any parameter, such as:
Max (6, 20, 40, 10, 50, 30, 40) should also be accepted, returning the maximum value of 50.
How is this going to be achieved?
In fact, such an example we have seen, the most typical is the printf function, you can see the original printf function:
int printf (char*, ...);
It takes a format string and follows any specified parameters, determining the number of arguments according to the actual need.
In fact its implementation depends on the meaning of a standard C Library <stdarg.h>,stdandard argument (standard parameter). The following is a brief introduction to <STDARG.H>, or the efficacy of <cstdarg> in C + +:

The

First is the memory format of the parameter: The parameter is stored in the stack segment of the memory, and in the execution of the function, the stack is entered from the last one.  So the bottom high address, the top low stack address, for example:
void func (int x, float y, char z);
So, when the function is called, the argument char z advanced stack, then the float y, and finally the int x, so in memory the variables are stored in the order of x->y->z, so theoretically, we just have to detect the address of any one variable, and know the type of other variables, With pointer shift operations, you can always find other input variables. The
is then the variable-Entry table format, with the omitted arguments ... Instead, it must be noted that:
1. There can only be one ... And it must be the last parameter;
2. Do not use only one ... As all arguments, as you can tell from the back, you cannot determine the address of the entry list.
For example, declare a function as follows:
void func (int x, int y, ...); The
is then called: Func (3, 5, ' C ', 2.1f, 6); The
then when the parameter is called, the compiler will not check what the actual input parameters, but all the parameters as described above, into the actual arguments stacked in memory, in this case, in memory x=3, y=5, ' C ', 2.1f, 6
But there is a need to pay attention to the place, These things are stacked in memory just next to each other, so to call these parameters correctly, you must know their exact type , and we also care about the actual length of the parameter table, but unfortunately, we don't know. Therefore, this solution is by no means brilliant, and to some extent, it is even a serious loophole. Therefore, C + + does not advocate to use it.

However, the shortcomings of the shortcomings, we still have to use the last resort, but we have input variables in the time, should have a clear understanding of the type of entry, otherwise such operations are very dangerous.
Here is <stdarg.h> on the implementation of the above idea, a few important macro definitions are as follows:
typedef char* Va_list; /* Can be understood as an array of argv in int main (int argc,char *argv[]) */
void Va_start (Va_list ap, Prev_param); /* ANSI version */
Type Va_arg (va_list ap, type); /* Get the first parameter, you need to specify the parameter type */
void Va_end (va_list ap); /* The va_list is actually empty */
Where Va_list is a character pointer that can be understood as a pointer to the current parameter, the fetch parameter must be done through this pointer.

All macros that support variadic functions are defined in Stdarg.h and varargs.h. For example, in standard ANSI form, these macros are defined as:

typedef char * VA_LIST; string pointers

#define _INTSIZEOF (N) ((sizeof (n) + sizeof (int)-1) & ~ (sizeof (int)-1))

#define VA_START (AP,V) (AP = (va_list) &v + _intsizeof (v))

#define VA_ARG (Ap,t) (* (t *) (AP + = _intsizeof (t))-_intsizeof (t)))

#define VA_END (AP) (AP = (va_list) 0)

The macro _intsizeof is used to align pointers in integer bytes, because the parameters in the stack are full number sections (pointers or values) below the C call protocol.

<step 1> before invoking the parameter table, a variable of type va_list should be defined for later use (assuming that the Va_list type variable is defined as an AP);
<step 2> should then initialize the AP to point to the first parameter in the variable parameter table, which is implemented by Va_start, the first parameter is the AP itself, and the second parameter is a variable next to the variable argument list;
<step 3> then gets the parameter, calls Va_arg, its first parameter is the AP, the second parameter is the specified type of the parameter to get, then returns the value of the specified type, and points the position of the AP to the next variable position of the parameter list;
<step 4> Get all the parameters, we need to turn off the AP pointer to avoid danger, by calling Va_end, which is the input parameter, the AP is set to NULL, and should form the habit of closing the pointer after getting the parameter table.

For example the beginning of the example int max (int n, ...); The inside of its function should be implemented like this:
int max (int n, ...) {//Parameter n indicates the number of subsequent arguments, bound, not mistaken in input
Va_list ap; Define a va_list pointer to access the parameter table
Va_start (AP, N); Initialize the AP to point to the first argument
int maximum = -0X7FFFFFFF; This is a minimal integer.
int temp;
for (int i = 0; i < n; i++) {
TEMP = Va_arg (AP, int); To get an int parameter, you must specify the type, otherwise an error occurs, and the AP refers to the next parameter
if (Maximum < temp) Maximum = temp;
}
Va_end (AP); Aftercare work, close AP, Release va_list
return Max;
}
Test the behavior of the MAX function in the main function (c + + format)
int main () {
cout << Max (3, ten, +) << Endl;
cout << Max (6, +, +, ten, (), +) << Endl;
}

Variable-parameter functions are defined in different forms under different systems.

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

Type funcname (Type para1, type Para2, ...);

With regard to this definition, there are three points to note:

In general, this form requires at least one normal formal parameter, and the variable parameter is passed through three '. ' To define the. So "..." does not mean ellipsis, but part of the function prototype. The type is a function return value and a form parameter. For example:

int myprintf (char const* fmt, ...);

However, we can also define functions like this:

void MyFunc (...);

However, in this case, we cannot use the parameters of the function because each parameter cannot be extracted from the macro described above. So unless your function code does not actually use any of the parameters in the parameter table, you must use at least one common parameter in the parameter table.

Note that the mutable parameter can only be at the end of the function parameter table. Can't do this:

void MyFunc (..., int i);


Basic usage explained to this point, you can see that this method has two very serious vulnerabilities: first, the type of input parameters arbitrary, so that the parameters can easily be an incorrect type to get a value (such as the input of a float, but the int type to get him), so that there will be inexplicable results of the operation; The size of the parameter list cannot be obtained at run time, so there is a possibility of access out of bounds, resulting in a serious runtime ERROR. As a suggestion, try not to use this method in the C + + environment, if necessary, consider using classes or overloads instead, which can be a good way to compensate for the vulnerability of this method.

#define_crt_secure_no_warnings#include<stdio.h>#include<string.h>#include<stdarg.h>#include<stdlib.h>/*function prototype declaration, need at least one definite parameter, note the ellipsis in parentheses*/intDemoChar*,...);voidMainvoid) {Demo ("DEMO"," This"," is","a","Demo"," /");}intDemoChar*msg,...) {va_list argp;/*define the structure of the save function parameter*/    intArgno =0;/*number of record parameters*/    Char*para;/*The string parameter that holds the fetch*/    //use the macro va_start to point ARGP to the first optional parameter passed in.//Note that MSG is the last determined parameter in the parameter table, not the first parameter in the parameter tableVa_start (ARGP, msg);  while(1)    {        //Take out the current parameter, type char *//If you do not give the correct type, you will get the wrong argumentPara = Va_arg (ARGP,Char*); if(STRCMP (Para," /") ==0)/*end With empty string indicating parameter input*/             Break; printf ("parameter #%d is:%s\n", Argno, para); Argno++;//Note: Stack bottom at high address, stack top at low address, so here is + +} va_end (ARGP); /*set ARGP to null*/System ("Pause"); return 0;}

The above content is reproduced to the Cattle People blog: http://foggy-elves.blog.sohu.com/

Variable parameter functions in C + +

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.