Main Content

Too many va_arg calls for current argument list

Number of calls to va_arg exceeds number of arguments passed to variadic function

Description

This defect occurs when the number of calls to va_arg exceeds the number of arguments passed to the corresponding variadic function. The analysis raises a defect only when the variadic function is called.

Too many va_arg calls for current argument list does not raise a defect when:

  • The number of calls to va_arg inside the variadic function is indeterminate. For example, if the calls are from an external source.

  • The va_list used in va_arg is invalid.

Risk

When you call va_arg and there is no next argument available in va_list, the behavior is undefined. The call to va_arg might corrupt data or return an unexpected result.

Fix

Ensure that you pass the correct number of arguments to the variadic function.

Examples

expand all

#include <stdarg.h>
#include <stddef.h>
#include <math.h>

/* variadic function defined with
* one named argument 'count'
*/
int variadic_func(int count, ...) {
    int result = -1;
    va_list ap;
    va_start(ap, count);
    if (count > 0) {
        result = va_arg(ap, int);
        count --;
        if (count > 0) {
/* No further argument available 
* in va_list when calling va_arg
*/	

            result += va_arg(ap, int);
        }
    }
    va_end(ap);
    return result;
}

void func(void) {

    (void)variadic_func(2, 100); 

}

In this example, the named argument and only one variadic argument are passed to variadic_func() when it is called inside func(). On the second call to va_arg, no further variadic argument is available in ap and the behavior is undefined.

Correction — Pass Correct Number of Arguments to Variadic Function

One possible correction is to ensure that you pass the correct number of arguments to the variadic function.

#include <stdarg.h>
#include <stddef.h>
#include <math.h>

/* variadic function defined with
* one named argument 'count'
*/

int variadic_func(int count, ...) {
    int result = -1;
    va_list ap;
    va_start(ap, count);
    if (count > 0) {
        result = va_arg(ap, int);
        count --;
        if (count > 0) {

/* The correct number of arguments is
* passed to va_list when variadic_func()
* is called inside func()
*/			
            result += va_arg(ap, int); 
        }
    }
    va_end(ap);
    return result;
}

void func(void) {

    (void)variadic_func(2, 100, 200); 

} 

Result Information

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

Version History

Introduced in R2018a