Тип битовых полей без знака: 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 10

2 ответа:

Похоже, что эта двусмысленность уже была выявлена комитетом по стандартам, поскольку в нынешнем проекте уточняется это предложение:

Если int может представлять все значения исходный тип (в соответствии с ограничениями ширина, для битового поля), значение преобразуется в int;

Я читаю то же, что и вы: беззнаковое битовое поле размером с int должно иметь тип unsigned int, меньший, чем int, он должен иметь тип signed int.

Компиляторы, к которым у меня есть доступ (gcc на x86, Sun CC на Sparc, IBM xlC на POWER), имеют поведение, соответствующее этому чтению (печать 1 в вашей программе, печать 0, если битовое поле уменьшено до 31 бита или подписано).