メインコンテンツ

MISRA C:2012 Rule 23.5

A generic selection should not depend on implicit pointer type conversion

R2024a 以降

説明

ルール定義

A generic selection should not depend on implicit pointer type conversion 1 .

This rule comes from MISRA C™:2012 Amendment 3.

根拠

総称選択の制御式では lvalue 変換が行われ、変換後の値の型が関連リストの型と比較されます。完全一致が見つかるまでは、既定の関連が選択されます。コンパイラは、既定以外の関連と一致させるための制御式の型の暗黙的な変換を行いません。汎用関連付けを使用して汎用関数を実装する場合、非総称 C 関数とは異なり、汎用関数の引数に対して暗黙的な変換は行われません。これは予期しない動作であり、正確でない結果が発生する可能性があります。

Polyspace 実装

コンパイラが制御式の型と既定の関連の型の間で暗黙的なポインター変換を実行する場合、ルール チェッカーは違反を報告します。ポインターの型に基づいていない選択の場合、ルール チェッカーは違反を報告しません。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

この例では、関数 generic_func() は総称関数であり、総称選択マクロを使用して引数の型に基づいてアクションを選択します。総称選択マクロは、const long long* 型、const long* 型、const int* 型に対応しています。generic_func() の引数がこれらのいずれの型とも正確に一致しない場合、既定の関連が選択されます。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int func_ll(const long long *);
int func_l(const long *);
int func_i(const int *);
int func_any(void *);
#define generic_func(x) (_Generic((x), const long long*: func_ll, const long*: func_l, const int*: func_i, default: func_any)(x))

int main() {
	int i = -5;
	long l = -10L;
	long long ll = -15LL;
	double d = -20.0;

	generic_func(&i);  //Noncompliant
	generic_func(&l);  //Noncompliant
	generic_func(&ll); //Noncompliant
	generic_func(&d);  //Noncompliant

	return 0;
}

関数 main() では、暗黙的なポインター型変換を必要とする型を使用して総称選択が実行されます。たとえば &iint* 型が、generic_func の関連リストにあるどの型名とも一致しないとします。コンパイラは汎用関数の呼び出し時に暗黙的なポインター型変換を実行しないため、generic_func(&i) を実行すると、func_i() ではなく関数 func_any() が呼び出されます。これが原因で、正確でない結果が発生する可能性があります。ルール チェッカーは、暗黙的なポインター変換を必要とする呼び出しに対し、違反を報告します。

チェック情報

グループ: 総称選択
カテゴリ: 推奨
AGC カテゴリ: 推奨

バージョン履歴

R2024a で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace® Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.