メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

va_start の誤った使用

va_start を可変個引数関数でない関数で呼び出している、または可変個引数関数の右端のパラメーターでない 2 番目の引数を指定して呼び出している

説明

この欠陥は、va_start マクロをその仕様に違反する方法で使用した場合に発生します。

次のような可変個引数関数 (可変個の引数をもつ関数) を考えます。

void multipleArgumentFunction(int someArg, int rightmostFixedArg, ...) {
    va_list myList;
    va_start(myList, rightmostFixedArg);
    ...
    va_end(myList);
}
va_start マクロは、可変個引数関数の固定パラメーターの後にある追加引数をリスト内で取得できるように可変引数リストを初期化します。前の例で、va_start マクロは rightmostFixedArg の後の引数を取得できるように myList を初期化します。

va_start の仕様の違反には複数の可能性があります。次に例を示します。

  • 可変個引数関数でない関数で va_start を呼び出している。

  • va_start の 2 番目の引数が、可変個引数関数の右端の固定パラメーターではない。

リスク

va_start マクロの仕様に違反すると、コンパイル エラーが発生する可能性があります。コンパイラが違反を検出できない場合、この違反により、未定義の動作が発生する可能性があります。

修正方法

以下を確認します。

  • 可変個引数関数で va_start マクロを使用している

  • va_start マクロの 2 番目の引数が、可変個引数関数の右端の固定パラメーターである

未定義の動作や処理系定義の動作を回避するには、可変個引数関数の使用を最小限にします。可変個引数関数の使用を検出するには、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 マクロの 2 番目の引数として使用されています。

修正 — 可変個引数関数の固定パラメーターの順序を変更

1 つの修正方法として、右端の固定パラメーターが 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
影響度: Medium

バージョン履歴

R2019a で導入