How to get warning when comparing two enum value
How to get warning when comparing two enum value
In this small DEMO in Objective-C:
first enum:
typedef NS_ENUM(NSUInteger, Day) {
DaySunday,
DayMonday,
DayTuesday
};
second enum:
typedef NS_ENUM(NSUInteger, Month) {
MonthJanuary,
MonthFebruary,
MonthMarch,
MonthApril
};
when comparing :
Day sunday = DaySunday;
Month january = MonthJanuary;
if (sunday == january) {
NSLog(@"case1 with warning");
}
if (DaySunday == january) {
NSLog(@"case2 without warning");
}
and Xcode snapshot:
so how could i get a warning in case2?
sorry stupid paste,fixed
– user7333304
Jul 2 at 12:08
Maybe if you use Day.DaySunday then it will show the warning. Currently its taking both the values as Integers only.
– Nishu Priya
Jul 2 at 12:11
3 Answers
3
Enumeration types in (Objective-)C are very weak types. By the C Standard every enumeration constant (your january
etc.) has an integer type, not the type of the enumeration. Furthermore a value of enumeration type is implicitly converted to an integer type when needed.
january
Clang is giving you a warning when both operands are of enumeration type, and it is only a warning as by the C Standard the comparison is a correct when between integer values.
In your DaySunday == january
the left operand has integer type, the right operand is implicitly convert to integer type, so again this is perfectly legal and correct Standard C. Clang could choose to issue a warning, why it does not is probably down to a design decision, or consequence of the design, on Clang internals.
DaySunday == january
Be thankful Clang often gives warnings where Standard C does not require them, however you cannot rely on it showing all the traps in C.
To address your issue you can cast the literal to the enum type if you wish, (Day)DaySunday == january
, but you might reasonably decide this makes C look even worse ;-)
(Day)DaySunday == january
I'm not sure why this behavior is happening, but it's strange and cool. To get the warning, you have to cast DaySunday
as type Day
explicitly.
DaySunday
Day
if ((Day)DaySunday == january) {
NSLog(@"case2 without warning");
}
Explicitly casting january
as Month
won't trigger the warning, so it looks like the static analyzer is correctly treating january
as a Month
type (because you declared it that way), but is implicitly converting DaySunday
to make the comparison work.
january
Month
january
Month
DaySunday
To be fair, the warning in the first case is actually not the ideal behavior, because both Day
and Month
are NSUIntegers and therefore are comparable. As you observe when you run this code, both comparisons are true, meaning the warning isn't actually meaningful.
Day
Month
You have to change enum to int for removing Warning
if ((int)sunday == (int)january) {
NSLog(@"case1 with warning");
}
The question is asking how cause a warning, not how to prevent a warning.
– rmaddy
Jul 2 at 16:07
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
I think you added the same enum twice in your example. The day-enum is missing.
– TMob
Jul 2 at 11:58