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: консультация