Сравнение битового поля с целым числом (отрицательное), undefined или ошибками компилятора?

Вот небольшая программа. Должно ли это печатать 0 или 1 или имеет поведение undefined?

#include <stdio.h>
struct S0 {
  unsigned f1 : 1;
};

struct S0 s;

int main (void) {
  int x = -3;
  int y = x >= (0, s.f1);
  printf ("%d\n", y);
  return 0;
}

Это взято из теста resent CSmith, и этот случай обсуждается более здесь.

В частности, GCC, KCC и CompCert выдает 0, а MSVC 2010, ICC 12.0.2 и последние результаты Clang 1.

Ответы

Ответ 1

Интересный вопрос.

В соответствии с проектом стандарта C99 6.5.17.1 тип (0, s.f1) совпадает с типом s.f1, который (на 6.7.2.1.9) является "целым числом без знака, состоящим из 1 бит". Это арифметический тип из-за того, что он является целым типом, его точность равна 1 (в соответствии с 6.2.6.2.6 и 6.2.6.1.3 не содержит битов заполнения), поэтому его ранг меньше, чем у int ( по второму элементу под 6.3.1.1.1, int имеет точность не менее 15, так как он должен иметь возможность представлять значения в диапазоне от -32767 до 32767 (см. 5.2.4.2.1)).

Поскольку как x, так и выражение (0, s.f1) имеют арифметический тип, выполняются обычные арифметические преобразования (в соответствии с 6.5.8.3). Так как int может представлять весь диапазон значений s.f1, ему присваивается (подписанный) int (согласно 6.3.1.1.2). Тогда, поскольку оба операнда являются (подписанными) ints, общий реальный тип подписан int (согласно 6.3.1.8), и поэтому результат сравнения должен быть 0.

Ответ 2

AFAIK, тип s.f1 равен unsigned int. Я считаю, что оператор запятой - красная сельдь; это сравнение эквивалентно int y = x >= s.f1;. Применяя "обычные арифметические преобразования" (C99 6.3.1.8), при выполнении сравнения x преобразуется в unsigned int; это преобразование хорошо определено (это приведет к UINT_MAX-2, поэтому оно будет больше. Таким образом, ответ должен быть 1.

Ответ 3

Я добавлю это здесь, комментарий № 39 от Rajan Bhakta, здесь,

Это двусмысленность в стандарте, который был очищен в Предстоящая последняя редакция стандарта ISO C (обычно известная как C1X пока он не будет ратифицирован) в пункте 6.3.1.1 параграфа 2. В сущности, тип битового поля (из результата выражения запятой) преобразуется к int, и, следовательно, сравнение представляет собой подписанное сравнение int. В сущность, стандарт C1X говорит, что значение y равно 0.

Буду признателен, если кто-нибудь сможет подтвердить это.