Прежде всего, синтаксис 0b
является нестандартным, поэтому пока неизвестно, что он будет делать.Один только этот синтаксис является нарушением MISRA;Я бы рекомендовал вместо этого использовать шестнадцатеричные константы.Во всяком случае, ваш код не должен содержать никаких «магических чисел».
Если мы предположим, что ваш компилятор обрабатывает нестандартные 0b
целочисленные константы так же, как и обычные десятичные целочисленные константы, то их тип равен (подписано) int
.Результатом вашей операции является подписанное int, «по существу подписанное», как называет его MISRA.Но вы сохраняете его в uin32_t
, который по существу не имеет знака, что является нарушением MISRA и причиной ошибки.
Обратите внимание, что у операторов сдвига всегда есть тип левого операнда, который повышается до целого числа.Так что писать что-то вроде 0b10 << 10u
не поможет.Как правило, никогда не использует побитовые операторы для подписанных операндов.
Также обратите внимание, что ?:
своеобразно, поскольку содержит неявное преобразование 2-го и 3-го операндов - онисбалансированный к тому же типу (согласно «обычным арифметическим преобразованиям»).Это может привести к незначительным ошибкам, поэтому лучше не указывать ?:
при использовании небольших целочисленных типов или типов со знаком (или, если применимо, MISRA).
Я бы также рекомендовал переписатькод для чего-то с меньшим количеством «магических чисел»:
#define MASK_SOMETHING (0x2u << 10) // give this some meaningful name
#define MASK_EMPTY (0x0u << 10) // give this some meaningful name
uint32_t num = 0U;
bool Flag = false;
...
if(Flag)
{
num |= MASK_SOMETHING;
}
Очевидно, что поразрядное ИЛИ против нуля не очень важно, может быть, вы хотели очистить биты вместо этого, если флаг не установлен?В этом случае вам нужно else { num &= ~MASK_EMPTY; }
.
(Это также можно оптимизировать, чтобы избавиться от ветви.)