8

I'm somewhat familiar with the typedef enum syntax of C and C++. I'm now programming in Objective-C and came across the syntax in the following example. I'm not sure if the syntax is Objective-C specific or not. But, my question is in the following code snippet, what does syntax like 1 << 0 mean?

typedef enum {
   CMAttitudeReferenceFrameXArbitraryZVertical = 1 << 0,
   CMAttitudeReferenceFrameXArbitraryCorrectedZVertical = 1 << 1,
   CMAttitudeReferenceFrameXMagneticNorthZVertical = 1 << 2,
   CMAttitudeReferenceFrameXTrueNorthZVertical = 1 << 3
} CMAttitudeReferenceFrame;
MikeyE
  • 1,756
  • 1
  • 18
  • 37
  • Thanks Carl for the post. Just an FYI, I did search before posting. But I didn't know it was called bit shifting. – MikeyE Jul 27 '13 at 05:33
  • No problem, that's what we're here for. =) – Carl Norum Jul 27 '13 at 05:44
  • You question answered here: [define SOMETHING `(1 << 0)`](http://stackoverflow.com/questions/15095350/define-something-1-0) and to understand `<<` operator [vies this](http://stackoverflow.com/questions/15708493/what-is-the-meaning-of-this-declaration/15708566#15708566) – Grijesh Chauhan Jul 27 '13 at 07:01
  • I see that someone tagged my question as a duplicate. I looked at the article titled Absolute Beginner's Guide to Bit Shifting, before I posted my question. My question isn't a duplicate, because I specified my question is specific to Objective-C. While I know Objective-C is derived from C, it's possible that Apple might have added some additional bit shifting capabilities to Objective-C. Hence, I asked my question specific to Objective-C. – MikeyE Mar 30 '15 at 00:51

3 Answers3

14

This is common to the C-family of languages, and works identically in C, C++, and Objective-C. Unlike Java, Pascal, and similar languages, a C enum is not limited to the values named for it; it actually is an integral type of a size that can represent all the named values, and one can set a variable of the enum type to an arithmetic expression in the enum members. Typically, one uses bit shifts to make the values powers of 2, and one uses bit-wise logical operations to combine values.

typedef enum {
   read    = 1 << 2,  // 4
   write   = 1 << 1,  // 2
   execute = 1 << 0   // 1
} permission;  // A miniature version of UNIX file-permission masks

Again, the bit-shift operations are all from C.

You can now write:

permission all = read | write | execute;

You could even include that line in the permission declaration itself:

typedef enum {
   read    = 1 << 2,  // 4
   write   = 1 << 1,  // 2
   execute = 1 << 0,  // 1
   all     = read | write | execute // 7
} permission;  // Version 2

How do you turn execute on for a file?

filePermission |= execute;

Note that this is dangerous:

filePermission += execute;

This will change something with value all to 8, which makes no sense.

Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
6

<< is called the left shift operator.

http://www.techotopia.com/index.php/Objective-C_Operators_and_Expressions#Bitwise_Left_Shift

Long story short 1 << 0 = 1, 1 << 1 = 2, 1 << 2 = 4 and 1 << 3 = 8.

Snow Blind
  • 1,164
  • 7
  • 12
3

It looks like the typedef is representing a bit field value. 1 << n is 1 shifted left n bits. So each enum item represents a different bit setting. That particular bit set or clear would indicate something being one of two states. 1 shifted left by zero bits is 1.

If a datum is declared:

CMAttitudeReferenceFrame foo;

Then you can check any one of four independent states using the enum values, and foo is no bigger than an int. For example:

if ( foo & CMAttitudeReferenceFrameXArbitraryCorrectedZVertical ) {
    // Do something here if this state is set
}
lurker
  • 56,987
  • 9
  • 69
  • 103