MISRA C:2012 Rule 10.1

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

Описание

Определение правила

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

Объяснение

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

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

Категория основных типовСтандартные типы

По существу, логический

bool или _Bool (определено в stdbool.h)

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

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

char

По существу enum

именованные enum

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

подписанные char, со знаком short, со знаком int, со знаком long, со знаком long long

По существу беззнаковый

неподписанные char, без знака short, без знака int, без знака long, без знака long long

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

float, double, long double

Усиление и обоснование

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

ОперацияКатегория арифметического операнда существенного типа
ОператорОперандБулевсимволenumподписанныйнеподписанныйплавание
[ ]целое число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. В арифметической операции не используйте операнд по существу типа enum. Объект перечисления использует целый тип, заданную реализацией. Поэтому операция с использованием объекта перечисления может привести к результату с неожиданным типом.

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

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

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

Обратите внимание, что для типа битового поля, если битовое поле реализовано как:

  • Логическое, битовое поле по существу является логическим.

  • Тип со знаком или без знака, битовое поле по существу подписано или не подписано соответственно.

    Тип битового поля является наименьшим типом, который может представлять битовое поле. Для образца введите stmp вот по существу 8 бит целого числа:

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

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

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

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

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

#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 нарушается из-за:

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

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

Примечание

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

Примечание

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

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

Группа: Модель Essential Type
Категория: Требуемая
Категория СМЖЛ: Консультационная