Namespaces
Variants

va_start

From cppreference.com
 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
Integer comparison functions
(C++20)(C++20)(C++20)    
(C++20)
Swap and type operations
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Common vocabulary types
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
Defined in header <cstdarg>
void va_start( std::va_list ap, parmN );
(until C++26)
void va_start( std::va_list ap, ... );
(since C++26)

The va_start macro enables access to the variable arguments of a variadic function.

va_start shall be invoked with an instance to a valid std::va_list object ap before any calls to va_arg.

The parameter parmN must name the rightmost parameter in the parameter list of the function definition (the one just before the ellipsis parameter).

If parmN is of reference type, or of a type not compatible with the type that results from default argument promotions, the behavior is undefined.

If parmN is a pack expansion or an entity resulting from a lambda capture, the program is ill-formed, no diagnostic required.

(since C++11)
(until C++26)

If more than one argument is present for va_start, the preprocessing tokens comprising the second and subsequent arguments are discarded. If any of those arguments expands to include unbalanced parentheses, or a preprocessing token that does not convert to a token, the program is ill-formed, no diagnostic required.

(since C++26)

Parameters

ap - an object of the va_list type
parmN - the named parameter preceding the first variable parameter

Expanded value

(none)

Notes

va_start is required to work correctly even if its second parameter has overloaded operator&.

It is unspecified whether va_start can be evaluated in a constant expression.

(since C++11)

Example

#include <cstdarg>
#include <iostream>

#if __cplusplus >= 202603L
int add_nums(int count, ...) // omission of ‘,’ before “...” is deprecated in C++26
#else
int add_nums(int count...) // OK until C++26
#endif
{
    int result = 0;
    std::va_list args;
    va_start(args, count); // “count” can be omitted since C++26
    for (int i = 0; i < count; ++i)
        result += va_arg(args, int);
    va_end(args);
    return result;
}

#if __cplusplus >= 202603L
int add_nums_cpp26(...) // since C++26 a named argument is no longer required
{
    int result = 0;
    std::va_list args;
    va_start(args);
    int count = va_arg(args, int);
    for (int i = 0; i < count; ++i)
        result += va_arg(args, int);
    va_end(args);
    return result;
}
#endif

int main()
{
    std::cout << add_nums(4, 25, 25, 50, 50) << '\n';
#if __cplusplus >= 202603L
    std::cout << add_nums_cpp26(4, 25, 25, 50, 50) << '\n';
#endif
}

Possible output:

150
150

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 273 C++98 it was unclear whether va_start is required to
support parmNs with overloaded operator&
required
LWG 2099 C++98 the behavior was undefined if parmN is
declared with a function, array, or reference type
the behavior is undefined if
parmN is of reference type

See also

accesses the next variadic function argument
(function macro) [edit]
ends traversal of the variadic function arguments
(function macro) [edit]
C documentation for va_start