Описание
Неправильный тип данных передал va_arg когда тип данных в va_arg
вызов не совпадает с типом данных variadic аргумента функции что va_arg
чтения.
Например, вы передаете unsigned char
аргумент к variadic функционирует func
. Из-за продвижения параметра по умолчанию аргумент продвинут на int
. Когда вы используете va_arg
вызовите, который читает unsigned char
аргумент, несоответствие типов происходит.
void func (int n, ...) {
...
va_list args;
va_arg(args, unsigned char);
...
}
void main(void) {
unsigned char c;
func(1,c);
}
Риск
В функции variadic (функционируют с переменным количеством аргументов), вы используете va_arg
считать каждый аргумент из списка аргументов переменной (va_list
). va_arg
использование не гарантирует, что там на самом деле существует аргумент, чтобы читать или что тип данных аргумента совпадает с типом данных в va_arg
вызвать. Необходимо убедиться, что оба условия верны.
Чтение неправильного типа с va_arg
вызов может привести к неопределенному поведению. Поскольку аргументы функции находятся на стеке, вы можете получить доступ к нежелательной области стека.
Фиксация
Убедитесь, что тип данных аргумента, переданного функции variadic, совпадает с типом данных в va_arg
вызвать.
Аргументы функции variadic подвергаются продвижениям параметра по умолчанию. Типы данных аргумента функции variadic не могут быть определены из прототипа. Аргументы таких функций подвергаются продвижениям параметра по умолчанию (см. Секунду. 6.5.2.2 и 7.15.1.1 в Стандарте C99). Целочисленные аргументы подвергаются целочисленному продвижению и аргументам типа float
продвинуты на double
. Для целочисленных аргументов, если тип данных может быть представлен int
, например, char
или short
, это продвинуто на int
. В противном случае это продвинуто на unsigned int
. Все другие аргументы не подвергаются продвижению.
Чтобы избежать неопределенного и заданного реализацией поведения, минимизируйте использование функций variadic. Используйте средства проверки в MISRA C:2012 Rule 17.1
или MISRA C++:2008 Rule 8-4-1
обнаружить использование функций variadic.
Пример - char
Используемый в качестве типа аргумента функции и va_arg
аргумент
#include <stdarg.h>
#include <stdio.h>
unsigned char func(size_t count, ...) {
va_list ap;
unsigned char result = 0;
va_start(ap, count);
if (count > 0) {
result = va_arg(ap, unsigned char);
}
va_end(ap);
return result;
}
void func_caller(void) {
unsigned char c = 0x12;
(void)func(1, c);
}
В этом примере, func
берет unsigned char
аргумент, который подвергается продвижению параметра по умолчанию int
. Тип данных в va_arg
вызовом является все еще unsigned char
, который не совпадает с int
тип аргумента.
Коррекция — использует int
как va_arg
Аргумент
Одна возможная коррекция должна считать int
аргумент с va_arg
.
#include <stdarg.h>
#include <stdio.h>
unsigned char func(size_t count, ...) {
va_list ap;
unsigned char result = 0;
va_start(ap, count);
if (count > 0) {
result = va_arg(ap, int);
}
va_end(ap);
return result;
}
void func_caller(void) {
unsigned char c = 0x12;
(void)func(1, c);
}