Знаковое/беззнаковое несоответствие

Мне трудно понять природу проблемы, с которой я столкнулся в своем коде. Линия

if ((struct.c == 0x02) && (struct2.c == 0x02) && (struct.s == !struct2.s))
    {/**/}

где c равно int, а s равно uint64_t производит

C4388: '==' знаковое/беззнаковое несоответствие

предупреждение. Я понимаю, что это за предупреждение, я не вижу, что его вызывает. Что мне не хватает?


person Sven    schedule 24.06.2015    source источник
comment
struct — зарезервированное ключевое слово в C. Я бы не рекомендовал использовать его в качестве имени переменной.   -  person r3mainer    schedule 24.06.2015
comment
Это только для иллюстрации   -  person Sven    schedule 24.06.2015
comment
и это код C, верно?   -  person Sourav Ghosh    schedule 24.06.2015
comment
Да, бывает   -  person Sven    schedule 24.06.2015
comment
Если тип источника - bool, значение false преобразуется в ноль, а значение true преобразуется в значение одного типа назначения, числовые преобразования. Я предполагаю, что это приведет к типу назначения uint64_t, что сделает вопрос только C. Зачем тогда добавлять тег C++?   -  person too honest for this site    schedule 24.06.2015


Ответы (2)


Прямое цитирование стандарта C11, глава §6.5.3.3 (выделено мной).

Результатом операции логического отрицания ! является 0, если значение его операнда при сравнении не равно 0, 1, если значение его операнда при сравнении равно 0. Результат имеет тип int....

Таким образом, результатом логического оператора ! является int, поэтому !struct2.s дает значение int, а выражение

....(struct.s == !struct2.s)

создает проблему.


ПРИМЕЧАНИЕ 1:

Я предполагаю, что вы используете struct в качестве имени структуры только для иллюстрации, в противном случае, struct является зарезервированным ключевым словом в C, вы не можете использовать его в качестве имени переменной.


ЗАМЕТКА 2:

Возможно, вы на самом деле имели в виду (struct.s != struct2.s), но это всего лишь (вероятное) предположение.


FOOTNOTE :: Предыдущий вопрос также помечал C++, перемещая его как сноску, но сохраняя информацию только для справки.
Что касается C++, возвращаемый тип !bool. Ссылка: C++11, глава § 5.3.3 (опять же, мое выделение)

Операнд оператора логического отрицания ! в противном случае контекстуально преобразуется в bool(Clause 4); its value istrueif the converted operand isfalseand false. Тип результата – bool.

person Sourav Ghosh    schedule 24.06.2015
comment
@JensGustedt Просто добавил это, хотя и в качестве примечания. Спасибо. :-) - person Sourav Ghosh; 24.06.2015
comment
Работает как шарм, спасибо. Что касается цели операции, то struct.s == !struct2.s было именно то, к чему я стремился, но спасибо за заботу :) - person Sven; 24.06.2015
comment
Дает ли отрицание также int для С++? Или это будет bool там? - person too honest for this site; 24.06.2015
comment
@Sven Не за что. :-) Кстати, вы можете рассмотреть возможность принятия ответа, который вам помог. - person Sourav Ghosh; 24.06.2015

[слишком длинно для комментария]

Чтобы получить максимальную отдачу от предупреждений компилятора, всегда старайтесь помещать только один оператор/выражение в одну строку (по крайней мере временно, когда пытаетесь определить источник ошибки/предупреждения).

Итак, если бы вы установили код таким образом:

if (
    (struct.c == 0x02) 
    && (struct2.c == 0x02) 
    && (struct.s == !struct2.s)
  )

Компилятор указал вам точно на (относительно) 4-ю строку.

person alk    schedule 24.06.2015