MISRA C:2012 Rule 10.8

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

Описание

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

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

Объяснение

Составное выражение является непостоянным выражением с помощью составного оператора. В Существенной Модели Типа составные операторы:

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

  • Дополнение (бинарный +двоичный файл-)

  • Поразрядно (&, |, ^)

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

  • Условное выражение (?, :)

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

(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.

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

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