Main Content

Incorrect use of va_start

va_start is called in a non-variadic function or called with a second argument that is not the rightmost parameter of a variadic function

Description

This defect occurs when you use the va_start macro in a way that violates its specifications.

In a variadic function or function with variable number of arguments:

void multipleArgumentFunction(int someArg, int rightmostFixedArg, ...) {
    va_list myList;
    va_start(myList, rightmostFixedArg);
    ...
    va_end(myList);
}
The va_start macro initializes a variable argument list so that additional arguments to the variadic function after the fixed parameters can be captured in the list. In the preceding example, the va_start macro initializes myList so that it can capture arguments after rightmostFixedArg.

You can violate the specifications of va_start in multiple ways. For instance:

  • You call va_start in a non-variadic function.

  • The second argument of va_start is not the rightmost fixed parameter of the variadic function.

Risk

Violating the specifications of the va_start macro can result in compilation errors. If the compiler fails to detect the violation, the violation can result in undefined behavior.

Fix

Make sure that:

  • The va_start macro is used in a variadic function

  • The second argument of the va_start macro is the rightmost fixed parameter of the variadic function.

To avoid undefined and implementation-defined behavior, minimize the use of variadic functions. Use the checkers for MISRA C:2012 Rule 17.1 or MISRA C++:2008 Rule 8-4-1 to detect use of variadic functions.

Examples

expand all

#include <stdarg.h>

double addVariableNumberOfDoubles(int num, double* weight, ...) {
    double sum=0.0;
    va_list list;
    va_start(list, num);
    for(int i=0; i < num; i++) {
        sum+=weight[i]*va_arg(list, double);
    }
    va_end(list);
    return sum;
}

In this example, the rightmost fixed parameter to the addVariableNumberOfDoubles function is weight. However, a different parameter is used as the second argument to the va_start macro.

Correction — Switch Order of Fixed Parameters of Variadic Function

One possible correction is to modify the order of fixed parameters to the variadic function so that the rightmost fixed parameter is used for the va_start macro.

#include <stdarg.h>

double addVariableNumberOfDoubles(double* weight, int num, ...) {
    double sum=0.0;
    va_list list;
    va_start(list, num);
    for(int i=0; i < num; i++) {
        sum+=weight[i]*va_arg(list, double);
    }
    va_end(list);
    return sum;
}

Result Information

Group: Programming
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: VA_START_MISUSE
Impact: Medium

Version History

Introduced in R2019a