Использование малого целого числа с оператором бит в C
В связи с предыдущим вопросом я не могу понять некоторые правила MISRA C 2004.
В ISO C99 draft 2007, в разделе 6.5 §4:
Некоторые операторы (унарный оператор ~ и бинарные операторы <, → , &, ^ и |, совместно описываемые как побитовые операторы), должны иметь операнды, которые имеют целочисленный тип. Эти операторы дают значения, которые зависят от внутренних представлений целых чисел, и имеют определенные для реализации и undefined аспекты для подписанных типов.
Хорошо, используя знаковое целое с побитовыми операторами, может создавать поведение undefined (и не имеет смысла).
Хорошим решением является использование явного преобразования в более широкий беззнаковый целочисленный тип для обхода интегральной рассылки, а затем не использовать знаковое значение с побитовыми операторами (см. связанные ответы моего предыдущего вопроса).
Но в MISRA C 2004 возможно использование небольших целых без знака с побитовыми операторами (например, правило 10.5). Почему, если интегральное продвижение приводит к использованию подписанных значений с побитовыми операторами? Я думаю, что я не понимаю некоторых вещей.
Ответы
Ответ 1
Правила не противоречат друг другу, и вам не нужно расширять тип. Вы можете сразу же вернуть результат двоичной операции с небольшим двоичным кодом обратно в свой тип.
Маленькое целое число не будет повышаться до int для сдвигов, если первый операнд не является int.
Это из их примера:
uint8_t port = 0x5aU;
uint8_t result_8;
uint16_t result_16;
result_8 = (~port) >> 4; /* not compliant */
result_8 = ((uint8_t)(~port)) >> 4; /* compliant */
result_16 = ((uint16_t)(~(uint16_t)port)) >> 4; /* compliant */