Incorrect use of va_start

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

Описание

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

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

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

Можно нарушать спецификации va_start несколькими способами. Для образца:

  • Звоните va_start в неверадической функции.

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

Риск

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

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

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

  • The 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++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : VA_START_MISUSE
Влияние: Средний
Введенный в R2019a