MISRA C:2012 Rule 10.1

Операнды не должны иметь несоответствующего существенного типа

Описание

Управляйте определением

Операнды не должны иметь несоответствующего существенного типа.

Объяснение

Что такое существенные типы?

Существенная категория типа задает существенный тип объекта или выражения.

Существенная категория типаСтандартные типы

По существу булевская переменная

bool или _Bool (заданный в stdbool.h)

Можно также задать типы, которые являются чрезвычайно булевым использованием опции Effective boolean types (-boolean-types).

По существу символ

char

По существу перечисление

названный enum

По существу подписанный

char со знаком, short со знаком, int со знаком, long со знаком, long long со знаком

Чрезвычайно без знака

char без знака, short без знака, int без знака, long без знака, long long без знака

По существу плавание

float'double', long double

Усиление и объяснение

Для операндов некоторых операторов вы не можете использовать определенные существенные типы. В приведенной ниже таблице каждая строка представляет комбинацию оператора/операнда. Если существенный столбец типа не пуст для той строки, существует ограничение MISRA при использовании того типа как операнд. Номер в таблице соответствует списку объяснений после таблицы.

ОперацияСущественная категория типа арифметического операнда
ОператорОперандБулевская переменнаясимволперечислениесо знакомбез знакаплавание
[ ]целое число34   1
+ (унарный) 345   
- (унарный) 345 8 
+ -также3 5   
* /также345   
%также345  1
< > <= >=также3     
== !=также      
! && ||любой 22222
<< >>левый345,66 1
<< >>право3477 1
~ & | ^любой345,66 1
?:1-й 22222
?:2-й и 3-й      

  1. Выражение чрезвычайно типа с плавающей точкой для этих операндов является нарушением ограничений.

  2. Когда операнд будет интерпретирован как булево значение, используйте выражение по существу булева типа.

  3. Когда операнд будет интерпретирован как числовое значение, не используйте операнд по существу булева типа.

  4. Когда операнд будет интерпретирован как числовое значение, не используйте операнд чрезвычайно типа символов. Числовые значения символьных данных заданы реализацией.

  5. В арифметической операции не используйте операнд по существу перечислимого типа. Перечислимый объект использует заданный реализацией целочисленный тип. Операция, включающая перечислимый объект, может поэтому привести к результату с неожиданным типом.

  6. Выполните только операции сдвига и битовые операции на операндах типа чрезвычайно без знака. Когда вы используете операции сдвига и битовые операции на чрезвычайно типах со знаком, получившееся числовое значение задано реализацией.

  7. Чтобы избежать неопределенного поведения на отрицательных сдвигах, используйте правый операнд чрезвычайно без знака.

  8. Для оператора унарный минус не используйте операнд типа чрезвычайно без знака. Реализованный размер int определяет со знаком из результата.

Дополнительное сообщение в отчете

operand_name операнд operator_name оператор имеет несоответствующую существенную категорию типа category_name.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

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

typedef unsigned char boolean;

extern float f32a;
extern char cha; 
extern signed char s8a;
extern unsigned char u8a;
enum enuma { a1, a2, a3 } ena; 	

extern boolean 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 нарушено потому что:

  • Оператор && ожидает только чрезвычайно булевы операнды. Однако по крайней мере один из используемых операндов имеет другой тип.

  • Первый операнд ?: как ожидают, будет по существу булевской переменной. Однако различный тип операнда используется.

Примечание

Для Polyspace®, чтобы обнаружить нарушение правила, необходимо задать имя типа boolean как эффективный булев тип. Для получения дополнительной информации смотрите Effective boolean types (-boolean-types).

typedef unsigned char boolean;


enum enuma { a1, a2, a3 } ena; 
enum { K1 = 1, K2 = 2 };    /* Essentially signed */
extern char cha, chb; 
extern boolean bla, blb, rbla; 
extern signed char rs8a, s8a;


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 нарушено потому что операторы * и > не ожидайте чрезвычайно булевы операнды. Однако операнды, используемые здесь, являются по существу булевской переменной.

Примечание

Для Polyspace, чтобы обнаружить нарушение правила, необходимо задать имя типа boolean как эффективный булев тип. Для получения дополнительной информации смотрите Effective boolean types (-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 нарушено потому что операторы & и << не ожидайте чрезвычайно символьные операнды. Однако по крайней мере один из операндов, используемых здесь, имеет чрезвычайно тип символов.

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 нарушено потому что арифметические операторы --, * и += не ожидайте чрезвычайно перечислимые операнды. Однако по крайней мере один из операндов, используемых здесь, имеет по существу перечислимый тип.

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

Проверяйте информацию

Группа: существенная модель типа
Категория: необходимый
Категория AGC: консультация