2014-10-07 2 views
10

Связанных с previous question, я не могу понять некоторые правила MISRA C 2004Использование небольшого целого с оператором бит в C

В ISO C99 draft 2007, в 6.5 раздела § 4:

Некоторых операторов (унарный оператор ~, а бинарные операторы < <, >>, &,^и |, совместно описываемые как побитовые операторы), должны иметь операнды с целым типом. Эти операторы дают значения, которые зависят от внутренних представлений целых чисел, и имеют определенные для реализации и неопределенные аспекты для подписанных типов.

ОК, используя целое число со знаком с побитовыми операторами, может производить неопределенное поведение (и не имеет смысла).

Хорошим решением является использование явного преобразования в более широкий беззнаковый целочисленный тип, чтобы обходить интегральную рекламу, а затем не использовать знаковое значение с побитовыми операторами (см. Связанные ответы моего предыдущего вопроса).

Но в MISRA C 2004 возможно использование небольших целых без знака с побитовыми операторами (например, правило 10.5). Почему, если интегральное продвижение приводит к использованию подписанных значений с побитовыми операторами? Думаю, я не понимаю некоторых вещей.

+1

Я не уверен, что понял вопрос, но это не имеет значения, если беззнаковое значение повышен до большего типа. Положительные числа и беззнаковые числа, меньшие, чем максимальное значащее значение, выглядят одинаково, т. Е. Знаковый бит равен 0. – Caleb

+0

Беззнаковые целочисленные типы не приведут к подписанию int из-за интегральной рекламы. например unsigned short всегда будет беззнаковым int и никогда не будет подписанным int. – mch

+4

@mch Не верно для систем, где short и int имеют разный размер. Если unsigned short может помещаться внутри 'int', он будет передан в' int', который будет подписан. – Lundin

ответ

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 */ 
+4

-1 этот ответ неправильный. См. C11 6.5.7 'Целочисленные рекламные акции выполняются для каждого из операндов. Тип результата - это продвинутый левый операнд. « – Lundin

+0

Я имел в виду результат, который чтит подпись:« Результат E1 >> E2 - это правые позиции E2 в E1. Если E1 имеет неподписанный тип или если E1 имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью частного E1/2E2. « –

+2

E1 и E2 относятся к операндам после целочисленного продвижения. Текст, который вы цитируете, относится к плохо заданному поведению, которое возникает, когда вы перемещаете вещи в и из знаковых бит отрицательного числа. – Lundin

 Смежные вопросы

  • Нет связанных вопросов^_^