va_start に渡された不正な型のデータ
va_start マクロの 2 番目の引数のデータ型による未定義の動作の発生
説明
この欠陥は va_start マクロの第 2 引数が以下のいずれかのデータ型である場合に発生します。
既定の引数プロモーションが行われている際に変化するデータ型。
たとえば、
charおよびshortがintまたはunsigned intにプロモーションされ、floatがdoubleにプロモーションされるとします。int型とdouble型は既定の引数プロモーションの際に変化しません。(C のみ) レジスタ型または
register修飾子で宣言されているデータ型。(C++ のみ) 参照データ型。
(C++ のみ) 非トリビアル コピー コンストラクターまたは自明でない移動コンストラクターをもつデータ型。
リスク
次のような可変個引数関数 (可変個の引数をもつ関数) を考えます。
void multipleArgumentFunction(int someArg, short rightmostFixedArg, ...) {
va_list myList;
va_start(myList, rightmostFixedArg);
...
va_end(myList);
}va_start マクロは、可変個引数関数の固定パラメーターの後にある追加引数をリスト内で取得できるように可変引数リストを初期化します。C11 および C++14 規格によると、フラグが設定されたいずれかのデータ型を va_start マクロの 2 番目の引数 (前の例では rightmostFixedArg) で使用する場合、動作は未定義です。データ型が非トリビアル コピー コンストラクターに関連している場合、動作は処理系定義になります。たとえば、コピー コンストラクターが va_start の呼び出しの中で呼び出されるかどうかは、コンパイラによって異なります。
修正方法
va_start マクロを使用する際、可変個引数関数の右端の名前付きパラメーターに対して int 型、unsigned int 型、または double 型の使用を試みます。その後、このパラメーターを va_start マクロの 2 番目の引数として使用します。
たとえば、次の例では、可変個引数関数の右端の名前付きパラメーターのデータ型は、サポートされているデータ型 int です。
void multipleArgumentFunction(int someArg, int rightmostFixedArg, ...) {
va_list myList;
va_start(myList, rightmostFixedArg);
...
va_end(myList);
}未定義の動作や処理系定義の動作を回避するには、可変個引数関数の使用を最小限にします。可変個引数関数の使用を検出するには、MISRA C:2012 Rule 17.1 または MISRA C++:2008 Rule 8-4-1 のチェッカーを使用します。
例
結果情報
| グループ: プログラミング |
| 言語: C | C++ |
| 既定値: 手書きコードはオン、生成コードはオフ |
コマンド ライン構文: VA_START_INCORRECT_TYPE |
| 影響度: Medium |
バージョン履歴
R2019a で導入