Недопустимый операнд для операторов «››» и «&» (MISRA C)

При проверке кода с помощью Misra он генерировал следующие сообщения

Unpermitted operand to operator '>>' [MISRA 2012 Rule 10.1 required]
Unpermitted operand to operator '&' [MISRA 2012 Rule 10.1 required]

Мне не удалось разобраться в проблеме, а описание правила 10.1 носит очень общий характер и мало помогает. Соответствующий фрагмент кода приведен ниже.

float  variable2;
variable2= 814.00f;
Data[0] = (((Int16) variable2) >> 8) & ((Int16)0xFF);
Data[1] =  ((Int16) variable2) & ((Int16)0xFF);

В чем проблема с использованием операторов в этом коде?


person user145760    schedule 07.03.2019    source источник
comment
Может быть, потому что Int16 - знаковый тип?   -  person Jabberwocky    schedule 07.03.2019
comment
Я подумал, но это также для &. Возможно, MISRA не любит потерю значимости, даже если актерский состав обычно скрывает это.   -  person Weather Vane    schedule 07.03.2019


Ответы (1)


Вы никогда не должны использовать целые числа со знаком в побитовой арифметике. С этим связано много плохо определенного поведения. Сдвиг отрицательного значения влево дает неопределенное поведение. Сдвиг вправо отрицательного значения дает поведение, определяемое реализацией (арифметический или логический сдвиг).

Поэтому MISRA-C требует, чтобы все такие переменные имели то, что они называют по существу беззнаковым типом.

Кроме того, использование 16-битного типа независимо от подписи небезопасно в 32-битной системе, потому что они будут неявно повышены до 32-битного подписанного int. Я предполагаю, что вы используете 32-битную систему, в противном случае использование чисел с плавающей запятой, вероятно, в первую очередь не имеет большого смысла.

В вашем случае вы не можете напрямую перейти от float к unsigned, так как вы потеряете бит знака. Это означает, что вам нужно сначала перейти на один шаг к подписанному типу.

float    f32 = 814.00f;
int32_t  s32 = (int32_t)f32;
uint32_t u32 = (uint32_t)s32;

Data[0] = ((u32 >> 8) & 0xFFu);
Data[1] = (u32 & 0xFFu);

Это должно быть совместимо с MISRA-C, хотя это также зависит от типа Data.

  • Суффикс u для целочисленных констант достаточно, их не нужно преобразовывать.
  • Используйте типы stdint.h, а не некоторые самодельные типы.
  • Дополнительные скобки вокруг операндов & необходимы для рекомендаций MISRA-C: 2012 12.1. Ваш код не соответствует этому правилу, приведенный выше код соответствует.
person Lundin    schedule 07.03.2019