va_arg 的类型参数应符合要求
3.3.5 ID_badVaArgType
对于 stdarg.h 中的宏 va_arg(ap, type),其类型参数 type 在下列情况会导致标准未定义的行为:
- type 后加 * 号不能表示指针类型
- 与“默认参数提升”后的类型不兼容
- 与可变参数列表中对应的实参类型不兼容,或没有对应的实参
以下类型不可作为 va_arg 的参数:
bool、_Bool、
char、signed char、unsigned char、char16_t、
float、
short、unsigned short、signed short、
short int、signed short int、unsigned short int
这些类型的参数在传入可变参数列表时,会被提升为 int、unsigned int、double 等类型,va_arg 如果再按提升前的类型解析参数的值就会产生错误,参见“默认参数提升(default argument promotion)”机制。
另外,在 C++ 代码中,非“POD 类型”也不可作为 va_arg 的参数,参见 ID_nonPODVariadicArgument。
示例:
void foo(int n, ...) {
va_list ap;
va_start(ap, n);
for (int i = 0; i < n; i++) {
char c = va_arg(ap, char); // Non-compliant
....
}
va_end(ap);
}
例中 va_arg 的类型参数为 char 是不符合要求的。
应改为:
for (int i = 0; i < n; i++) {
char c = (char)va_arg(ap, int); // Compliant
....
}
相关
依据
ISO/IEC 9899:1999 7.15.1.1(2)-undefined
ISO/IEC 9899:2011 7.16.1.1(2)-undefined