Правило 10.1 MISRA C:2012

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

Описание

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

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

Объяснение

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

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

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

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

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

Если вы задаете булев тип через typedef, необходимо задать это имя типа прежде, чем закодировать проверку правил. Для получения дополнительной информации смотрите 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: консультация
Язык: C90, C99