17

I've seen others use Bitwise-OR to combine flags before:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN | JUMP | SHOOT;

That's also the way I do it.

But I've also seen some (not as many) combine flags using addition:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN + JUMP + SHOOT;

Which one is more "readable"? (Which one do you think more people will recognize?) What is the "standard" way to do it? Which one do you prefer?

2
  • This is a SO question. Consider using something like 1<<0, 1<<1, 1<<2, and so on. When you have many flags, it becomes more readable, more maintainable, less error-prone. For instance, if you are packing all 64 bits of a 64 bit int, you really want to avoid typos :) How you represent 1 is also important. For a 64 bit integer in VS2010 I think it is 1UI64, or something like that. Using a wrong type might bite you.
    – Job
    Dec 5, 2010 at 14:08
  • 3
    @Job: Not a StackOverflow question, because it's asking about readability, recognizability, preferences and best practices. No single objective answer for it; it belongs here.
    – Macneil
    Dec 26, 2010 at 16:32

2 Answers 2

37

Bitwise-OR.

Addition is dangerous.

Consider an example where a bandit is a person, and an angry bandit is a bandit that speaks and shoots. Later, you decide all bandits should shoot, but you've forgotten about the angry bandit definition and don't remove its shooting flag.

#define PERSON 1 << 0
#define SPEAKS 1 << 1
#define SHOOTS 1 << 2
#define INVINCIBLE 1 << 3
const byte bandit = PERSON | SHOOTS;                    // 00000101
const byte angryBandit_add = bandit + SPEAKS + SHOOTS;  // 00001011 error
const byte angryBandit_or = bandit | SPEAKS | SHOOTS;   // 00000111 ok

If you used angryBandit_add your game would now have the perplexing logic error of having angry bandits that can't shoot or be killed.

If you used angryBandit_or the worst you'd have is a redundant | SHOOTS.

For similar reasons, bitwise NOT is safer than subtraction for removing flags.

0
11

bitwise-OR conveys the intent more clearly

also, bitwise-OR should be more efficient

6
  • +1 indeed I also think that OR makes it more clear that those are flags, but concerning the efficiency there are languages where bitwise operations are slow, e.g. JavaScript all Numbers are 64 floats bitwise operators need to do implicit conversion on those.
    – Ivo Wetzel
    Dec 5, 2010 at 6:17
  • 1
    Given the OP's example, I don't think one line of ORs or addition is going to adversely impact the execution speed of a program. Dec 5, 2010 at 7:33
  • 1
    @Greg: especially since the calculation in that example will be done at compile time. :-) Dec 5, 2010 at 7:43
  • In addition to conveying the intent it's fairly common to see this in many languages including but not limited to ADA, C#, Java... Dec 5, 2010 at 12:41
  • 2
    "should" is a very big word in this business. While it is highly unlikely that you will encounter this issue today, I have very clear memories of working on a processor that did not have a bitwise-OR instruction. You could bitwise-AND in one instructn, and you could bitwise-XOR in one instruction, but bitwise-OR took two: an immediate bitwise-AND to turn the bit off, and an immediate bitwise-XOR to complement the newly-cleared bit, which of course set it. Dec 5, 2010 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.