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

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

Описание

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

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

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

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

  • Вы вызываете va_start в функции non-variadic.

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

Риск

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

Фиксация

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

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

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

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

Примеры

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

#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.

Исправление — порядок переключателя фиксированных параметров функции Variadic

Одно возможное исправление должно изменить порядок фиксированных параметров к функции variadic так, чтобы самый правый фиксированный параметр использовался для макроса 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