I2C_CCRH_FS | I2C_CCRH_DUTY
сама по себе совместима с MISRA.Оба операнда по существу без знака, так что подвыражение в порядке.Однако все еще существует неявное преобразование каждого операнда в int
.Практический результат имеет тип int
.
. В псевдокоде: когда вы делаете (result as int) | I2C_CCRH_CCR
, операнды перед неявным продвижением имеют типы int | uint8_t
.uint8_t
получит здесь целое число до int
.У вас есть операнды разной подписи.
(Я полагаю, что инструмент жалуется на 10,4, поскольку целочисленные продвижения являются частью обычного арифметического разговора, как и в 10,4.)
Это целоеВыражение не вызывает никаких проблем на практике, поэтому предупреждение в основном педантичное.Но представьте, если бы вы сделали ~(I2C_CCRH_FS | I2C_CCRH_DUTY) | I2C_CCRH_CCR)
без приведения - вы бы получили отрицательное число, что-то вроде 0xFFFFFFxx
, выраженное в дополнении к 2.Это может быть опасно.
Чтобы исправить это, у вас есть два варианта:
- Для каждой операции приведите результат обратно к предполагаемому типу.Часто это дух MISRA-C.
- Перед операцией приводите операнды к большому типу без знака.Обычно более читаемый IMO.
Обратите также внимание, что оператор ~
не должен использоваться со операндом со знаком!Это нарушение правила 10.1.Приведение обратно к uint8_t
должно быть сделано последним.
TL; DR.Как получить код, совместимый с MISRA:
Вы должны были бы сделать что-то наполовину ужасное, как это:
I2C->CCRH &= (uint8_t) ~ (uint8_t) ((uint8_t)(I2C_CCRH_FS | I2C_CCRH_DUTY) | I2C_CCRH_CCR)
Это немного беспорядок.Я бы вместо этого бросил заранее.Предполагается, что 32-битный процессор:
I2C->CCRH &= (uint8_t) ~( (uint32_t)I2C_CCRH_FS | // comment explaining FS
(uint32_t)I2C_CCRH_DUTY) | // comment explaining DUTY
(uint32_t)I2C_CCRH_CCR ); // comment explaining CCR
Вышеуказанный стиль полезен при работе с регистрами MCU и аналогичными.Этот код является приемлемым, но его можно еще упростить.
Если можно изменить определения на #define I2C_CCRH_FS 0x80u
, тогда вы получите:
I2C->CCRH &= (uint8_t) ~(I2C_CCRH_FS | I2C_CCRH_DUTY | I2C_CCRH_CCR);
, и он все равно будет совместим с MISRAиз-за удобного маленького суффикса u
, который нравится MISRA.