0 / 0 / 0
Регистрация: 22.09.2018
Сообщений: 37
|
|||||||||||
1 | |||||||||||
Результат сравнения signed и unsigned22.09.2018, 13:04. Показов 5791. Ответов 6
Метки нет (Все метки)
Добрый день! Помогите, пожалуйста, разобраться.
Почему при сравнении этих переменных выдает ложь:
0
|
22.09.2018, 13:04 | |
Ответы с готовыми решениями:
6
Почему результат сравнения int и unsigned int равен 1? Разобрать код с signed unsigned Представление типа как signed/unsigned Вывод на экран значений signed от unsigned |
1624 / 806 / 146
Регистрация: 13.06.2015
Сообщений: 3,266
|
|
22.09.2018, 14:39 | 2 |
chpokhead, все переменные типа char в Си неявно приводятся к типу int, поэтому в первом примере несоответствие знаковостей разрешается уже на этом этапе, а дальше просто сравниваются два int. В двух следующих примерах никакого неявного приведения типов не производится, и компилятор выдаёт предупреждения, что при подобном сравнении результат может получиться не тот, что надо, т.к. не знает, какое именно сравнение производить - знаковое или беззнаковое.
1
|
Вездепух
12793 / 6670 / 1795
Регистрация: 18.10.2014
Сообщений: 16,889
|
|
22.09.2018, 20:01 | 3 |
Сообщение было отмечено chpokhead как решение
Решение
В первом случае выполняются integral promotions и сравнение выполняется в рамках типа
int . Т.е. никакого сравнения signed и unsigned тут нет. Сравниваются два int значения: (int) c > (int) uc - разумеется ложь.Во втором случае смешанное signed/unsigned сравнение производится в домене типа unsigned int . То есть сравниваются (unsigned int) i и u . (unsigned int) i > u - истина.В третьем случае сначала производится integral promotion из char в int , а затем срабатывает правило из второго случая. То есть сравнивается (unsigned int) (int) c > u - истина.
1
|
635 / 390 / 75
Регистрация: 21.09.2008
Сообщений: 1,342
|
|||||||||||
22.09.2018, 20:02 | 4 | ||||||||||
chpokhead, чтобы знать, что творится "за фасадом" компилятора, то можно воспользоваться его опциями, генерирующие ассемблерный листинг. Для gcc это опция -S. Первый пример на ассемблере gcc 5.1.0 выдал следующий листинг:
Весьма полезны в gcc две опции (-Wall -Wextra), включающие выдачу предупреждений в подозрительных местах.
0
|
Вездепух
12793 / 6670 / 1795
Регистрация: 18.10.2014
Сообщений: 16,889
|
|
22.09.2018, 20:08 | 5 |
Это не верно. Правила языка С четко говорят, что при сравнении
unsigned int и int знаковый операнд неявно приводится к беззнаковому типу и сравнение делается в рамках беззнакового типа. Никакого "компилятор не знает, какое именно сравнение производить" тут нет и быть не может.Добавлено через 5 минут Это покажет, "что творится "за фасадом" компилятора", но нисколько не прибавит вам понимания правил языка. Без предварительного понимания этих правил от разбора ассемблерных листингов будет только огромный вред и масса впустую потраченного времени. Огромное количество феерических и сюрреалистических "теорий" о языке С было высосано именно из ассемблерных листингов "пионэрами", которые почему-то решили, что они что-то там поняли.
1
|
635 / 390 / 75
Регистрация: 21.09.2008
Сообщений: 1,342
|
|
22.09.2018, 20:28 | 6 |
TheCalligrapher, про правила языка Вы правы. Их надо знать. Однако всё равно надо также знать, чего там написал оптимизирующий компилятор. Например, забыли про volatile и получите перемещение переменной из памяти в регистр. И в прерывании огребаем проблемы.
0
|
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
|
|
22.09.2018, 22:26 | 7 |
И ещё я бы добавил, что в реальной программе лучше так вообще не писать, а при необходимости использовать явное приведение типов.
0
|
22.09.2018, 22:26 | |
22.09.2018, 22:26 | |
Помогаю со студенческими работами здесь
7
Каким бы стоило сделать тип char по умолчанию — signed или unsigned? Определение диапазонов переменных типов char, short, int и long (как signed, так и unsigned) Ошибка W8012: "Comparing signed and unsigned values" Тип signed char и unsigned char Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |