Недопустимый операнд для операторов «>>» и «&» (MISRA C) - PullRequest
3 голосов
/ 07 марта 2019

При проверке некоторого кода с помощью 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);

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

1 Ответ

4 голосов
/ 07 марта 2019

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

Поэтому 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. Ваш код не соответствует этому правилу, код выше.
...