Тип битовых полей без знака: int или unsigned int
Раздел 6.3.1.1 стандарта С99 содержит:
Следующее Может быть использовано в выражение везде, где
int
илиunsigned int
можно использовать:[...] Битовое поле типа
_Bool
,int
,signed int
, илиunsigned int
.Если
int
может представлять все значения для исходного типа значение равно преобразуется вint
; в противном случае оно преобразуется вunsigned int
.
Мне кажется, что это означает, что unsigned int
битовые поля повышаются до int
, за исключением случаев, когда ширина беззнакового битового поля равна ширине int
, в этом случае применяется последняя фраза.
У меня есть следующая программа:
struct S { unsigned f:32; } x = { 28349};
unsigned short us = 0xDC23L;
main(){
int r = (x.f ^ ((short)-87)) >= us;
printf("%dn", r);
return r;
}
И две системы для выполнения этой программы (int
является 32-разрядной на обеих системах). Одна система говорит, что эта программа печатает 1, а другая говорит, что она печатает 0. Мой вопрос в том, против какой из двух систем я должен подать отчет об ошибке? (Я склоняюсь к подаче отчета против системы, которая печатает 0, потому что отрывка выше)
2 ответа:
Похоже, что эта двусмысленность уже была выявлена комитетом по стандартам, поскольку в нынешнем проекте уточняется это предложение:
Если int может представлять все значения исходный тип (в соответствии с ограничениями ширина, для битового поля), значение преобразуется в int;
Я читаю то же, что и вы: беззнаковое битовое поле размером с int должно иметь тип unsigned int, меньший, чем int, он должен иметь тип signed int.
Компиляторы, к которым у меня есть доступ (gcc на x86, Sun CC на Sparc, IBM xlC на POWER), имеют поведение, соответствующее этому чтению (печать 1 в вашей программе, печать 0, если битовое поле уменьшено до 31 бита или подписано).