MISRA C:2012 Rule 10.8

Значение составного выражения не должно быть приведено к другой категории основных типов или к более широкому типу

Описание

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

Значение составного выражения не должно относиться к другой категории основных типов или к более широкому типу основных элементов.

Объяснение

Составное выражение является непостоянным выражением с использованием составного оператора. В модели Essential Type, композитные операторы:

  • Мультипликативный (*, /, %)

  • Добавка (двоичная +, двоичные -)

  • Побитовый (&, |, ^)

  • Сдвиг (<<, >>)

  • Условный (?, :)

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

(uint32_t) (u16a +u16b);
На 16-разрядной машине сложение выполняется в 16 битах. Результат оборачивается перед его приведением к 32 битам. На 32-разрядной машине сложение происходит в 32 битах и сохраняет биты высокого порядка, которые теряются на 16-разрядной машине. Приведение к более узкому типу с той же категорией основных типов приемлемо, поскольку явное усечение результатов всегда приводит к одной и той же потере информации.

Для получения дополнительной информации о важных типах смотрите MISRA C:2012 Rule 10.1.

Реализация Polyspace

Проверка правил поднимает дефект только в том случае, если результат составного выражения приведен к другому или более широкому существенному типу.

Например, в этом примере нарушение показано в первом назначении i но не второй. В первом присвоении составное выражение i+1 непосредственно приведен от подписанного к неподписанному типу. Во втором назначении составное выражение сначала приведено к тому же типу, а затем результат приведен к другому типу.

typedef int int32_T;
typedef unsigned char uint8_T; 
...
...
int32_T i;
i = (uint8_T)(i+1); /* Noncompliant */
i = (uint8_T)((int32_T)(i+1)); /* Compliant */

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

  • Значение составного выражения не должно относиться к другой категории основных типов.

  • Значение составного выражения не должно быть приведено к более широкому существенному типу.

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

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

Примеры

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

extern unsigned short ru16a, u16a, u16b;
extern unsigned int   u32a, ru32a;
extern signed int     s32a, s32b;

void foo(void)
{
  ru16a  = (unsigned short) (u32a + u32a);/* Compliant                           */
  ru16a += (unsigned short) s32a;    /* Compliant - s32a is not composite        */
  ru32a  = (unsigned int) (u16a + u16b);  /* Noncompliant - wider essential type */
}

В этом примере правило 10.8 нарушается в следующих случаях:

  • s32a и s32b по существу являются signed переменные. Однако результат ( s32a + s32b ) приведено к по существу unsigned тип.

  • u16a и u16b по существу являются unsigned short переменные. Однако результат ( s32a + s32b ) приведен к более широкому основному типу, unsigned int.

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

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