This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 21.10.1 - The features of <cstdarg> shall not be used
[C11] / 6.9.1; Undefined 8
[C11] / 7.16; Indeterminate 3
[C11] / 7.16.1.1; Undefined 2
[C11] / 7.16.1.2; Undefined 2
[C11] /
7.16.1.3; Undefined 2
[C11] / 7.16.1.4; Undefined 2, 3, 4
Category: Required
Analysis: Decidable,Single Translation Unit
Amplification
This rule also applies to the features of <stdarg.h>.
None of va_list, va_arg, va_start, va_end and va_copy shall be used.
Rationale
Passing arguments via an ellipsis bypasses the type checking performed by the compiler.
There are many instances of undefined behaviour associated with the features of <cstdarg>, including:
-
va_end not being used prior to end of a function in which va_start was used;
-
va_arg being used in different functions on the same va_list;
- The type of an argument not being compatible with the type specified to
va_arg.
Note: this rule does not restrict the use of existing library functions that are implemented as variadic function or the
declaration of functions that use the ellipsis.
Example
#include <cstdarg>
void h( va_list ap ) // Non-compliant
{
double y;
y = va_arg( ap, double ); // Non-compliant
}
void f( uint16_t n, ... )
{
uint32_t x;
va_list ap; // Non-compliant
va_start( ap, n ); // Non-compliant
x = va_arg( ap, uint32_t ); // Non-compliant
h( ap );
// Undefined behaviour - ap is indeterminate because va_arg used in h
x = va_arg( ap, uint32_t ); // Non-compliant
// Undefined behaviour - returns without using va_end
}
void g( void )
{
// Undefined behaviour - uint32_t / double type mismatch when f uses va_arg
f( 1, 2.0, 3.0 );
}
Copyright The MISRA Consortium Limited © 2023