Skip to content

Instantly share code, notes, and snippets.

@simonwhitaker
Created November 4, 2013 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonwhitaker/7301972 to your computer and use it in GitHub Desktop.
Save simonwhitaker/7301972 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
typedef NS_OPTIONS(uint32_t, SomeOption) {
SomeOptionNone = 0,
SomeOptionFoo = 1 << 0,
SomeOptionBar = 1 << 1,
};
int main(int argc, char *argv[]) {
@autoreleasepool {
SomeOption o = SomeOptionFoo|SomeOptionBar;
NSLog(@"o = %u", o);
}
}
@simonwhitaker
Copy link
Author

With -Wassign-enum I get a warning on line 11. I'd assumed I wouldn't get that as long as I used NS_OPTIONS.

$ clang -framework Foundation -Wassign-enum option-test.m -o option-test
option-test.m:11:24: warning: integer constant not in range of enumerated type 'SomeOption' (aka 'enum SomeOption')
      [-Wassign-enum]
        SomeOption o = SomeOptionFoo|SomeOptionBar;
                       ^
1 warning generated.

@samdeane
Copy link

samdeane commented Nov 4, 2013

if you declare SomeOptionAll = SomeOptionFoo | SomeOptionBar as part of your options, does the warning go away?

@samdeane
Copy link

samdeane commented Nov 4, 2013

I imagine that it ought to, as I'm assuming that the warning is really saying "that value is bigger than the biggest enum value you've declared".

It looks like NS_OPTION (and CF_OPTION) just declare the options as a typed enum, so there's no way for the compiler to know that it is valid to combine the values.

So all it could conceivably warn about is that the value of an assignment is larger than the largest enum value you defined.

It would probably require some sort of __option to be added to Clang to do more.

@danielctull
Copy link

So it seems to be a definite this value doesn't exist in the enum list warning.

For example if we add to Simon's example:

typedef NS_OPTIONS(uint32_t, SomeOption) {
    SomeOptionNone = 0,
    SomeOptionFoo = 1 << 0,
    SomeOptionBar = 1 << 1,
    SomeOptionBaz = 1 << 2,
    SomeOptionAll = (SomeOptionBar | SomeOptionFoo | SomeOptionBaz)
};

doing:

SomeOption option = (SomeOptionBar | SomeOptionFoo | SomeOptionBaz);

is fine, while

SomeOption option = (SomeOptionBar | SomeOptionFoo);

yields the same warning as before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment