Причина заключается в продвижении неявных типов. В этой единственной строке есть 3 неявных продвижения, что является опасным и неаккуратным стилем. У вас есть как целочисленное продвижение/обычные арифметические преобразования, так и неявное преобразование lvalue в одной строке кода.
Вы должны понимать, как эти покрытия работают в C, чтобы писать код C без ошибок, но вы также должны понимать их, чтобы использовать MISRA-C. На самом деле, одной из целей MISRA-C всегда было обучение программистов неявному продвижению типов — вы также найдете объяснения в документе MISRA-C.
Ваш код фактически нарушает несколько правил MISRA-C:2012. Не только 10.3, который касается неявных преобразований lvalue, но и 10.4:
Оба операнда оператора, в котором выполняются обычные арифметические преобразования, должны иметь одну и ту же категорию существенного типа.
var4
по существу подписано, а var5
по существу беззнаково. Поэтому недостаточно просто привести результат к соответствующему типу. Чтобы получить код, совместимый с MISRA-C, вы должны привести оба операнда к одному и тому же типу. Или лучше использовать для начала переменные соответствующего типа: нет особого смысла хранить результат -10 + 15
в переменной без знака. Либо вам нужны подписанные номера, либо нет.
Чтобы получить код, совместимый с MISRA-C, который также является полностью переносимым, это должен быть тип, который не может быть неявно повышен, например uint32_t
.
uint8_t var6 = (uint8_t) ((uint32_t)var4 + (uint32_t)var5);
альтернативно
int8_t var6 = (int8_t) ((int32_t)var4 + (int32_t)var5);
Это выражение является жестким, профессиональным C, поскольку оно не содержит ни одного неявного расширения. Это самодокументирующийся код, так как он показывает, что программист знает и учёл неявные продвижения типов. Это не влияет на производительность по сравнению с выражением только с 8-битными операндами, поскольку компилятор может оптимизировать его.
person
Lundin
schedule
29.11.2017