exponenta event banner

Неправильное использование va_start

va_start вызывается в непараметрической функции или вызывается со вторым аргументом, который не является самым правым параметром вариадической функции

Описание

Этот дефект возникает при использовании va_start макро таким образом, который нарушает его спецификации.

В переменной функции или функции с переменным числом аргументов:

void multipleArgumentFunction(int someArg, int rightmostFixedArg, ...) {
    va_list myList;
    va_start(myList, rightmostFixedArg);
    ...
    va_end(myList);
}
va_start макрос инициализирует список переменных аргументов, так что дополнительные аргументы для переменной функции после фиксированных параметров могут быть зафиксированы в списке. В предыдущем примере va_start инициализация макроса myList чтобы он мог фиксировать аргументы после rightmostFixedArg.

Вы можете нарушить спецификации va_start несколькими способами. Например:

  • Вы звоните va_start в неизменяемой функции.

  • Второй аргумент va_start не является самым правым фиксированным параметром переменной функции.

Риск

Нарушение технических требований va_start макрос может привести к ошибкам компиляции. Если компилятору не удается обнаружить нарушение, нарушение может привести к неопределенному поведению.

Зафиксировать

Убедитесь, что:

  • va_start макрос используется в переменной функции

  • Второй аргумент va_start макрос является самым правым фиксированным параметром переменной функции.

Во избежание неопределенного и определяемого реализацией поведения сведите к минимуму использование различных функций. Используйте шашки для MISRA C:2012 Rule 17.1 или MISRA C++:2008 Rule 8-4-1 обнаружение использования вариадных функций.

Примеры

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

#include <stdarg.h>

double addVariableNumberOfDoubles(int num, double* weight, ...) {
    double sum=0.0;
    va_list list;
    va_start(list, num);
    for(int i=0; i < num; i++) {
        sum+=weight[i]*va_arg(list, double);
    }
    va_end(list);
    return sum;
}

В этом примере самый правый фиксированный параметр addVariableNumberOfDoubles функция - weight. Однако в качестве второго аргумента используется другой параметр va_start макро.

Коррекция - изменение порядка фиксированных параметров вариадной функции

Одной из возможных корректировок является изменение порядка фиксированных параметров на переменную функцию так, чтобы самый правый фиксированный параметр использовался для va_start макро.

#include <stdarg.h>

double addVariableNumberOfDoubles(double* weight, int num, ...) {
    double sum=0.0;
    va_list list;
    va_start(list, num);
    for(int i=0; i < num; i++) {
        sum+=weight[i]*va_arg(list, double);
    }
    va_end(list);
    return sum;
}

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

Группа: Программирование
Язык: C | C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: VA_START_MISUSE
Воздействие: среднее
Представлен в R2019a