Недопустимый операнд для оператора ‘>>’ и ‘

#c #embedded #misra

#c #встроенный #misra

Вопрос:

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

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

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

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

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

Комментарии:

1. Может быть, потому, что Int16 это знаковый тип?

2. Я задавался этим вопросом, но это также для amp; . Возможно, MISRA не нравится потеря значимости, хотя приведение обычно скрывает это.

Ответ №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) amp; 0xFFu);
Data[1] = (u32 amp; 0xFFu);
  

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

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