|
1 | 1 | ---
|
2 | 2 | description: "Learn more about: Functions with Variable Argument Lists (C++)"
|
3 | 3 | title: "Functions with Variable Argument Lists (C++)"
|
4 |
| -ms.date: "11/04/2016" |
| 4 | +ms.date: 05/01/2025 |
5 | 5 | helpviewer_keywords: ["arguments [C++], variable number of", "variable argument lists", "declarators, functions", "argument lists [C++], variable number of", "declaring functions [C++], variables", "function calls, variable number of arguments"]
|
6 |
| -ms.assetid: 27c2f83a-21dd-44c6-913c-2834cb944703 |
7 | 6 | ---
|
8 | 7 | # Functions with Variable Argument Lists (C++)
|
9 | 8 |
|
10 |
| -Function declarations in which the last member of is the ellipsis (...) can take a variable number of arguments. In these cases, C++ provides type checking only for the explicitly declared arguments. You can use variable argument lists when you need to make a function so general that even the number and types of arguments can vary. The family of functions is an example of functions that use variable argument lists.`printf`*argument-declaration-list* |
| 9 | +Function declarations that have ellipsis (...) as the last argument take a variable number of arguments. C++ provides type checking only for the explicitly declared arguments. You can use variable argument lists when the number and types of arguments to the function can vary. The `printf` family of functions is an example of functions that have variable argument lists. |
11 | 10 |
|
12 | 11 | ## Functions with variable arguments
|
13 | 12 |
|
14 |
| -To access arguments after those declared, use the macros contained in the standard include file \<stdarg.h> as described below. |
| 13 | +To access arguments after those declared, use the macros contained in the standard include file `<stdarg.h>` as explained in this article. |
15 | 14 |
|
16 | 15 | **Microsoft Specific**
|
17 | 16 |
|
18 |
| -Microsoft C++ allows the ellipsis to be specified as an argument if the ellipsis is the last argument and the ellipsis is preceded by a comma. Therefore, the declaration `int Func( int i, ... );` is legal, but `int Func( int i ... );` is not. |
| 17 | +Microsoft C++ allows the ellipsis to be specified as an argument if the ellipsis is the last argument and a comma comes before the ellipsis. Therefore, the declaration `int Func( int i, ... );` is legal, but `int Func( int i ... );` isn't. |
19 | 18 |
|
20 | 19 | **END Microsoft Specific**
|
21 | 20 |
|
22 |
| -Declaration of a function that takes a variable number of arguments requires at least one placeholder argument, even if it is not used. If this placeholder argument is not supplied, there is no way to access the remaining arguments. |
| 21 | +Declaration of a function that takes a variable number of arguments requires at least one placeholder argument, even if it isn't used. If this placeholder argument isn't supplied, there's no way to access the remaining arguments. |
23 | 22 |
|
24 |
| -When arguments of type **`char`** are passed as variable arguments, they are converted to type **`int`**. Similarly, when arguments of type **`float`** are passed as variable arguments, they are converted to type **`double`**. Arguments of other types are subject to the usual integral and floating-point promotions. See [Standard Conversions](standard-conversions.md) for more information. |
| 23 | +When arguments of type **`char`** are passed as variable arguments, they're converted to type **`int`**. Similarly, when arguments of type **`float`** are passed as variable arguments, they're converted to type **`double`**. Arguments of other types are subject to the usual integral and floating-point promotions. For more information, see [Standard Conversions](standard-conversions.md). |
25 | 24 |
|
26 |
| -Functions that require variable lists are declared by using the ellipsis (...) in the argument list. Use the types and macros that are described in the \<stdarg.h> include file to access arguments that are passed by a variable list. For more information about these macros, see [va_arg, va_copy, va_end, va_start](../c-runtime-library/reference/va-arg-va-copy-va-end-va-start.md). in the documentation for the C Run-Time Library. |
| 25 | +Functions that require variable lists are declared by using the ellipsis (...) in the argument list. Use the types and macros that are described in the `<stdarg.h>` include file to access arguments that are passed by a variable list. For more information about these macros, see [va_arg, va_copy, va_end, va_start](../c-runtime-library/reference/va-arg-va-copy-va-end-va-start.md). |
27 | 26 |
|
28 |
| -The following example shows how the macros work together with the type (declared in \<stdarg.h>): |
| 27 | +The following example shows how to use the macros to process a variable argument list: |
29 | 28 |
|
30 | 29 | ```cpp
|
31 | 30 | // variable_argument_lists.cpp
|
| 31 | + |
32 | 32 | #include <stdio.h>
|
33 | 33 | #include <stdarg.h>
|
34 | 34 |
|
35 | 35 | // Declaration, but not definition, of ShowVar.
|
36 | 36 | void ShowVar( char *szTypes, ... );
|
| 37 | + |
37 | 38 | int main() {
|
38 | 39 | ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 );
|
39 | 40 | }
|
40 | 41 |
|
41 |
| -// ShowVar takes a format string of the form |
42 |
| -// "ifcs", where each character specifies the |
43 |
| -// type of the argument in that position. |
| 42 | +// ShowVar takes a format string of the form |
| 43 | +// "ifcs", where each character specifies the |
| 44 | +// type of the argument in that position. |
44 | 45 | //
|
45 |
| -// i = int |
46 |
| -// f = float |
47 |
| -// c = char |
48 |
| -// s = string (char *) |
| 46 | +// i = int |
| 47 | +// f = float |
| 48 | +// c = char |
| 49 | +// s = string (char *) |
49 | 50 | //
|
50 |
| -// Following the format specification is a variable |
51 |
| -// list of arguments. Each argument corresponds to |
52 |
| -// a format character in the format string to which |
| 51 | +// Following the format specification is a variable |
| 52 | +// list of arguments. Each argument corresponds to |
| 53 | +// a format character in the format string to which |
53 | 54 | // the szTypes parameter points
|
54 | 55 | void ShowVar( char *szTypes, ... ) {
|
55 | 56 | va_list vl;
|
56 | 57 | int i;
|
57 | 58 |
|
58 |
| - // szTypes is the last argument specified; you must access |
59 |
| - // all others using the variable-argument macros. |
| 59 | + // szTypes is the last argument specified; you must access |
| 60 | + // all others using the variable-argument macros. |
60 | 61 | va_start( vl, szTypes );
|
61 | 62 |
|
62 | 63 | // Step through the list.
|
63 | 64 | for( i = 0; szTypes[i] != '\0'; ++i ) {
|
| 65 | + |
64 | 66 | union Printable_t {
|
65 | 67 | int i;
|
66 | 68 | float f;
|
67 | 69 | char c;
|
68 | 70 | char *s;
|
69 | 71 | } Printable;
|
70 | 72 |
|
71 |
| - switch( szTypes[i] ) { // Type to expect. |
| 73 | + switch( szTypes[i] ) { // Type to expect |
72 | 74 | case 'i':
|
73 | 75 | Printable.i = va_arg( vl, int );
|
74 | 76 | printf_s( "%i\n", Printable.i );
|
75 |
| - break; |
| 77 | + break; |
76 | 78 |
|
77 | 79 | case 'f':
|
78 | 80 | Printable.f = va_arg( vl, double );
|
79 | 81 | printf_s( "%f\n", Printable.f );
|
80 |
| - break; |
| 82 | + break; |
81 | 83 |
|
82 | 84 | case 'c':
|
83 | 85 | Printable.c = va_arg( vl, char );
|
84 | 86 | printf_s( "%c\n", Printable.c );
|
85 |
| - break; |
| 87 | + break; |
86 | 88 |
|
87 | 89 | case 's':
|
88 | 90 | Printable.s = va_arg( vl, char * );
|
89 | 91 | printf_s( "%s\n", Printable.s );
|
90 |
| - break; |
| 92 | + break; |
91 | 93 |
|
92 | 94 | default:
|
93 |
| - break; |
| 95 | + break; |
94 | 96 | }
|
95 | 97 | }
|
96 | 98 | va_end( vl );
|
97 | 99 | }
|
98 |
| -//Output: |
99 |
| -// 32.400002 |
100 |
| -// a |
101 |
| -// Test string |
| 100 | +``` |
| 101 | +
|
| 102 | +```Output |
| 103 | +32.400002 |
| 104 | +a |
| 105 | +Test string |
102 | 106 | ```
|
103 | 107 |
|
104 | 108 | The previous example illustrates these important concepts:
|
105 | 109 |
|
106 | 110 | 1. You must establish a list marker as a variable of type `va_list` before any variable arguments are accessed. In the previous example, the marker is called `vl`.
|
107 |
| -
|
108 | 111 | 1. The individual arguments are accessed by using the `va_arg` macro. You must tell the `va_arg` macro the type of argument to retrieve so that it can transfer the correct number of bytes from the stack. If you specify an incorrect type of a size different from that supplied by the calling program to `va_arg`, the results are unpredictable.
|
109 |
| -
|
110 | 112 | 1. You should explicitly cast the result obtained by using the `va_arg` macro to the type that you want.
|
111 |
| -
|
112 |
| -You must call the macro to terminate variable-argument processing.`va_end` |
| 113 | +1. You must call the `va_end` macro to terminate variable-argument processing. |
0 commit comments