メインコンテンツ

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

MISRA C:2012 Rule 10.1

Operands shall not be of an inappropriate essential type

説明

ルール定義

Operands shall not be of an inappropriate essential type 1 .

根拠

実質的な型とは

実質的な型カテゴリはオブジェクトまたは式の実質的な型を定義します。

実質的な型カテゴリ標準的な型

実質的な boolean 型

bool または _Bool (stdbool.h で定義)

オプション [有効な boolean 型] (-boolean-types) を使用して、実質的な boolean 型を定義することもできます。

実質的な文字型

char

実質的な enum 型

名前付き enum

実質的な符号付き型

符号付き char、符号付き short、符号付き int、符号付き long、符号付き long long

実質的な符号なし型

符号なし char、符号なし short、符号なし int、符号なし long、符号なし long long

実質的な浮動小数点型

実数の浮動小数点型: floatdoublelong double

複素数の浮動小数点型: float _Complexdoble _Complexlong double _Complex

補足および根拠

一部の演算子のオペランドには、特定の実質的な型を使用できません。次の表で、各行は演算子とオペランドの組み合わせを表しています。実質的な型の列が対応する行に対して空白でない場合、その型をオペランドとして使用するときに MISRA による制約があります。表内の番号は表の後の根拠リストと対応します。

演算算術オペランドの実質的な型カテゴリ
演算子オペランドboolean文字enum符号付き符号なし浮動小数点
複素
[ ]整数34   19
+ (単項) 345    
- (単項) 345 8  
+ -いずれか3 5    
++ -- 3 5   9
* /いずれか345    
%いずれか345  19
< > <= >=いずれか3     9
== !=いずれか     1010
! && ||任意 222222
<< >>345、66 19
<< >>3477 19
~ & | ^任意345、66 19
?:1 番目 222222
?:2 番目と 3 番目       

  1. これらのオペランドに対する実質的な浮動小数点型の式は制約違反です。

  2. オペランドがブール値と解釈される場合、実質的な boolean 型の式を使用します。

  3. オペランドが数値と解釈される場合、実質的な boolean 型のオペランドを使用しません。

  4. オペランドが数値と解釈される場合、実質的な文字型のオペランドを使用しません。文字データの数値は処理系定義です。

  5. 算術演算では、実質的な enum 型のオペランドを使用しません。enum オブジェクトは処理系定義の整数型を使用します。そのため、enum オブジェクトを含む演算は予期しない型の結果となる場合があります。

  6. 実質的な符号なし型のオペランドでは、シフト演算とビット演算のみ実行します。実質的な符号付き型にシフト演算およびビット演算を使用すると、結果として得られる数値は未定義または処理系定義になります。

  7. 負のシフトでの未定義の動作を回避するには、実質的な符号なしの右辺のオペランドを使用します。

  8. 単項マイナス演算子には、実質的な符号なし型のオペランドを使用しません。実装された int のサイズが結果の符号属性を決定します。

  9. これらのオペランドに対する実質的な複素数の浮動小数点型の式は制約違反です。

  10. 浮動小数点型の比較は、予期しない実装依存の結果につながる可能性があります。浮動小数点型を比較するときには、浮動小数点の粒度 (FLT_EPSILON) と数値の大きさを考慮してください。

ビットフィールド型に関しては、ビットフィールドが次のように実装されている場合にどうなるかに注意してください。

  • boolean として実装されている場合は、ビットフィールドが実質的に boolean です。

  • 符号付き型または符号なし型として実装されている場合は、ビットフィールドが実質的に符号付きまたは符号なしです。

    ビットフィールドの型は、ビットフィールドを表現可能な最小の型です。たとえば、stmp 型は実質的に 8 ビットの整数です。

    typedef signed int mybitfield;
    typedef struct { mybitfield f1 : 1; } stmp;

実質的な型についての詳細は、MISRA C Rule 10.x の実質的な型を参照してください。

Polyspace 実装

Polyspace® は、演算のオペランドの実質的な型が不適切な場合に、このルールの違反を報告します。例外として、Polyspace は以下の場合には違反を報告しません。

  • 実質的な符号付き型の非負の整数定数式を、シフト演算子の右オペランドとして使用する場合。

  • 実質的な実数の浮動小数点型または実質的な複素数の浮動小数点型のオブジェクトを、定数リテラル 0、マクロ INFINITY または -INFINITY と比較する場合。

トラブルシューティング

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

すべて展開する

#include<stdbool.h>
extern float f32a;
extern char cha; 
extern signed char s8a;
extern unsigned char u8a,u8b,ru8a;
enum enuma { a1, a2, a3 } ena, enb; 	
extern bool bla, blb, rbla; 
void foo(void) {

	rbla = cha && bla;        /* Non-compliant: cha is essentially char  */
	enb = ena ? a1 : a2;      /* Non-compliant: ena is essentially enum  */
	rbla = s8a && bla;        /* Non-compliant: s8a is essentially signed char  */
	ena = u8a ? a1 : a2;      /* Non-compliant: u8a is essentially unsigned char  */
	rbla = f32a && bla;       /* Non-compliant: f32a is essentially float */
	rbla = bla && blb;        /* Compliant */
	ru8a = bla ? u8a : u8b;   /* Compliant */
}

この非準拠の例では、次の理由によりルール 10.1 に違反しています。

  • 演算子 && では、実質的な boolean 型のオペランドだけが必要である。しかし、使用されているオペランドの少なくとも 1 つは異なる型をもつ。

  • ?: の最初のオペランドには、実質的な boolean 型が必要である。しかしながら、異なるオペランドの型が使用されている。

メモ

Polyspace でルール違反を検出するには、型名 boolean を有効な boolean 型として定義しなければなりません。詳細は、有効な boolean 型 (-boolean-types)を参照してください。

#include<stdbool.h>
enum enuma { a1, a2, a3 } ena; 
enum { K1 = 1, K2 = 2 };    /* Essentially signed */
extern char cha, chb; 
extern bool bla, blb, rbla; 
extern signed char rs8a, s8a;
extern unsigned char u8a;

void foo(void) {

  rbla = bla * blb;      /* Non-compliant - Boolean used as a numeric value */
  rbla = bla > blb;      /* Non-compliant - Boolean used as a numeric value */

  rbla = bla && blb;     /* Compliant */
  rbla = cha > chb;      /* Compliant */
  rbla = ena > a1;       /* Compliant */ 
  rbla = u8a > 0U;       /* Compliant */
  rs8a = K1 * s8a;       /* Compliant - K1 obtained from anonymous enum */

}

この非準拠の例では、ルール 10.1 に違反しています。演算子 * および > では実質的な boolean 型のオペランドが想定されていません。しかし、ここで使用されているオペランドは、実質的な boolean 型です。

メモ

Polyspace でルール違反を検出するには、型名 boolean を有効な boolean 型として定義しなければなりません。詳細は、有効な boolean 型 (-boolean-types)を参照してください。

extern char rcha, cha, chb; 
extern unsigned char ru8a, u8a;

void foo(void) {

  rcha = cha & chb;      /* Non-compliant - char type used as a numeric value */
  rcha = cha << 1;       /* Non-compliant - char type used as a numeric value */

  ru8a = u8a & 2U;       /* Compliant */	
  ru8a = u8a << 2U;      /* Compliant */
 
}

この非準拠の例では、ルール 10.1 に違反しています。演算子 & および << では実質的な文字型のオペランドが想定されていません。しかし、ここで使用されるオペランドのうち少なくとも 1 つは、実質的な文字型です。

typedef unsigned char boolean;

enum enuma { a1, a2, a3 } rena, ena, enb; 

void foo(void) {

  ena--;             /* Non-Compliant - arithmetic operation with enum type*/
  rena = ena * a1;   /* Non-Compliant - arithmetic operation with enum type*/
  ena += a1;         /* Non-Compliant - arithmetic operation with enum type*/

}

この非準拠の例では、ルール 10.1 に違反しています。算術演算子 --* および += では、実質的な enum 型のオペランドが想定されていません。しかし、ここではオペランドの少なくとも 1 つは、実質的な enum 型が使用されています。

extern signed char s8a;
extern unsigned char ru8a, u8a;

void foo(void) {

  ru8a = s8a & 2;       /* Non-compliant - bitwise operation on signed type */
  ru8a = 2 << 3U;       /* Non-compliant - shift operation on signed type */
	
  ru8a = u8a << 2U;     /* Compliant */	

}

この非準拠の例では、ルール 10.1 に違反しています。演算 & および << は実質的な符号付きオペランドで実行してはなりません。しかし、ここで使用されるオペランドは符号付きです。

extern signed char s8a;
extern unsigned char ru8a, u8a;

void foo(void) {

  ru8a = u8a << s8a;    /* Non-compliant - shift magnitude uses signed type */	
  ru8a = u8a << -1;     /* Non-compliant - shift magnitude uses signed type */	

  ru8a = u8a << 2U;     /* Compliant */	
  ru8a = u8a << 1;      /* Compliant - exception */	

}

この非準拠の例では、ルール 10.1 に違反しています。演算 << では実質的な符号付き右オペランドが想定されていません。しかし、ここで使用される右オペランドは符号付きです。

#include <complex.h>
#include <stdbool.h>
#include <math.h>
_Complex float cnx, cny;
float fx;
void amd3() {

      cnx ? 1 : 0;                    // Noncompliant
      cny = !cnx;                     // Noncompliant
      cny = cnx && cny;               // Noncompliant
      cny = cnx || cny;               // Noncompliant
      if(fx != 0.0f) // Compliant
      {}
      if(cnx != INFINITY) // Compliant
      {}
}

この例では、Polyspace はルール 10.1 の違反を報告します。これは、演算子 == および != に実質的な浮動小数点型のオペランドが使用されているためです。例外として、これらのオペランドを使用して実質的な浮動小数点型オペランドを 0.0f および INFINITY と比較する場合は、違反ではありません。

チェック情報

グループ: 実質的な型モデル
カテゴリ: 必要
AGC カテゴリ: 推奨

バージョン履歴

すべて展開する


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.