Сравнение битового поля с (отрицательным) целым числом, неопределенным поведением или ошибками компилятора? - PullRequest
15 голосов
/ 14 июля 2011

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

#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;
}

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

В частности, выходы GCC, KCC и CompCert 0, тогда как MSVC 2010, ICC 12.0.2 и последние выходы Clang 1.

Ответы [ 3 ]

12 голосов
/ 14 июля 2011

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

В соответствии с черновым стандартом 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).Тогда, поскольку оба операнда являются (подписанными) целыми числами, общий действительный тип подписывается int (согласно 6.3.1.8), и поэтому результатом сравнения должно быть 0.

5 голосов
/ 14 июля 2011

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

0 голосов
/ 15 июля 2011

Я добавлю это сюда, это комментарий № 39 от Раджана Бхакты, здесь ,

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...