Сравнение значения битового поля без знака со значениями со знаком - PullRequest
0 голосов
/ 18 февраля 2019

при написании кода я наблюдаю одну вещь в моем коде, связанную с сравнением значения битового поля с отрицательными целыми числами.

У меня есть один элемент структуры без знака размером один бит и один без знака целое число.Когда я сравниваю отрицательное значение с переменной unsigned int, я получаю ожидаемый результат как 1, но когда я сравниваю элемент структуры с отрицательным значением, я получаю противоположный результат как 0.

#include <stdio.h>
struct S0
{
   unsigned int bit : 1;
};
struct S0 s;

int main (void) 
{
   int negVal = -3;
   unsigned int p = 123;
   printf ("%d\n", (negVal > p)); /*Result as 1 */
   printf ("%d\n", (negVal > s.bit));/*Result as 0 but expected 1 */
   return 0;
}

Я сомневаюсь, что еслиЯ сравниваю отрицательное значение с unsigned int, после чего происходит балансировка (неявное приведение типов).Но если я сравниваю член структуры unsigned int, почему неявное приведение типов не происходит.Поправьте меня, если я пропущу какие-либо основы битовых полей?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Для иллюстрации ниже используются 32-битные int и 32-битные unsigned int.

In negVal > p:

  • negVal - этоint со значением −3.
  • p является unsigned int со значением 123.
  • C 2018 6.5.8 3, в котором обсуждаются > и другие операторы отношений, говорит нам, что обычные арифметические преобразования выполняются над операндами.
  • 6.3.1.8 1 определяет обычные арифметические преобразования.Для целочисленных типов первым шагом обычных арифметических преобразований является выполнение целочисленных повышений для каждого операнда.
  • 6.3.1.1 2 определяет целочисленные преобразования.int, unsigned int, а целочисленные типы шире, чем они, остаются неизменными.Для других целочисленных типов говорится: «Если int может представлять все значения исходного типа (как ограничено шириной для битового поля), значение преобразуется в int;в противном случае он преобразуется в unsigned int. ”
  • Поскольку negVal является int, оно не изменяется целочисленными повышениями.
  • Поскольку p является unsigned int, оно не изменяется целочисленными преобразованиями.
  • Следующим шагом в обычных арифметических преобразованиях является преобразование одного операнда в тип другого.Для int и unsigned int int преобразуется в unsigned int.
  • Преобразование int −3 в unsigned int дает 4 294 967 293.(Преобразование определено для добавления или вычитания UINT_MAX + 1, что составляет 4 294 967 296, к значению столько раз, сколько необходимо, чтобы привести его в диапазон. Это эквивалентно «обертыванию» по модулю 4 294 967 296 или переосмыслению представления дополнения двух к −3как unsigned int.)
  • После преобразований выражение negVal > p стало 4294967293u > 123u.
  • Это сравнение верно, поэтому результат равен 1.

In negVal > s.bit:

  • negVal является int со значением −3.
  • s.bit является однобитовым битовым полем со значением0.
  • Как и выше, обычные арифметические преобразования выполняются с операндами.
  • Как и выше, первый шаг обычных арифметических преобразований заключается в выполнении целочисленных преобразований для каждого операнда.
  • Поскольку negVal является int, оно не изменяется целочисленными преобразованиями.
  • Поскольку s.bit битовое поле уже, чем int, оно будет преобразованоцелочисленные акции.Это однобитовое битовое поле может представлять либо 0, либо 1. Оба они могут быть представлены int, и поэтому правило «Если int может представлять все значения исходного типа (как ограничено шириной»).(для битового поля) значение преобразуется в int ”.
  • Преобразование 0 в int приводит к 0.
  • Следующий шаг в обычных арифметических преобразованияхбудет преобразовывать один операнд в тип другого.Поскольку оба операнда теперь int, преобразование не требуется.
  • После преобразований выражение negVal > s.bit стало -3 > 0.
  • Это сравнение неверно, поэтому результат равен0.
0 голосов
/ 18 февраля 2019

(переместите мое замечание в качестве ответа)

gcc повышает s.bit до int , поэтому (negVal > s.bit) делает (-3 > 0), оценивая 0

См. Должны ли битовые поля, меньшие чем int, быть предметом интегрального продвижения? но ваш вопрос не является его дубликатом.


(negVal > p) возвращает1 потому что negVal повышен до без знака , что приводит к большому значению, см. Сравнение со знаком / без знака

...