Incorrect data type passed to va_arg

Тип данных variadic аргумента функции не совпадает с типом в 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.

Примеры

развернуть все

#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); 
}

Информация о результате

Группа: Программирование
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: VA_ARG_INCORRECT_TYPE
Удар: носитель
ID CWE: 686
Введенный в R2018a