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

Трудно ми е да разбера естеството на проблема, който срещнах в моя код. Линия

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++-tag?   -  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), но това също е само (вероятно) предположение.


БЕЛЕЖКА ПОД ЛИНИЯ :: По-ранен въпрос също маркира 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 за C++? Или това ще бъде 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