ORing arguments together

Started by
6 comments, last by VanillaSnake21 16 years, 8 months ago
Hi, I'm a little confused on how ORing together arguments ( for example flags or options such as in Win32 (WM_MINIMIZED|WM_TOPMOST|WM_VISIBLE) ) I don't understand how that principle works, how can you combine three values together and then be able to uncombine them. For example lets say WM_MINIMIZED is 01h (or 1), WM_TOPMOST is 10h (2), and WM_VISIBLE is 11h (3), and if i OR them together the final result will be 11h. Which is the same as WM_VISIBLE. So how does the function that i pass these combined options knows that I passed 3 options and not just one WM_VISIBLE?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Advertisement
Well the answer is quite simple; you can't, not like that.
You need to think bitwise, not hex or decimal.

If you have 1, 10 and 100 for example, you can combine them with bitwise OR to 111. You can then use AND to check for specific bits.
Flags should generally be kept as single bits, otherwise some flags will simply override others.
<edit>Oops, too slow :)</edit>

When this approach is taken, each option is a unique bit, e.g.

OPT1 = 0x1,
OPT2 = 0x2,
OPT3 = 0x4,
OPT4 = 0x8,
OPT5 = 0x10,
etc...

So OPT1 | OPT3 | OPT4 = binary(01101) = 0x0D

Then to test if an option is present, you could do:

OPTIONS = 0x06;

if( OPTIONS & OPT1 ) // 0x06 & 0x1 = 0 = false
//opt1 code
if( OPTIONS & OPT2 ) // 0x06 & 0x2 = 2 = true
//opt2 code
if( OPTIONS & OPT3 ) // 0x06 & 0x4 = 4 = true
//opt3 code

Hope that helps :)
It works because those flags are designed to be ORed.

Let's consider 3 fictional flags, OPTION_1, OPTION_2, and OPTION_3.
These flags might be defined like this.

const int OPTION_1 = 1 << 0; // 1
const int OPTION_2 = 1 << 1; // 2
const int OPTION_3 = 1 << 2; // 4

When you pass a function the argument (OPTION_1 | OPTION_2 | OPTION_3), you're passing the binary value b111, or 7. As long as different flags are defined as powers of 2, they can be packed together as a single value.

Then to determine if OPTION_2 is set, for example, you would evaluate the statement (option & OPTION_2). When the two values are ANDed together, the bit representing OPTION_2 determines whether the statement returns true or false.
Typically each one is setting a certain bit in a DWORD. For instance..

FLAGA 0x00000001h;
FLAGB 0x00000002h;
FLAGC 0x00000004h;
FLAGD 0x00000008h;
FLAGE 0x00000016h;

You are ORing the bits together. so as you know (presumably) each of these in binary is:

FLAGA ...000001;
FLAGB ...000010;
FLAGC ...000100;
FLAGD ...001000;
FLAGE ...010000;

If I OR all of these together:

I would get ...011111; I can then AND the value with the certain flags to see if that particular bit is set.

Also 11h (doesn't equal 3) it equals 17 in hex. It would equal 3 if it were a binary representation.

I hope this helps.

USAGE
DWORD FlagsSet = FLAGA | FLAGD;  // FlagsSet = ...001001;CheckForFlags( FlagsSet ){     if (FlagsSet & FLAGA)          //perform some action     if (FlagsSet & FLAGB)          //perform some action     if (FlagsSet & FLAGC)          //perform some action ...     return ...;}
Quote:Original post by VanillaSnake21
Hi, I'm a little confused on how ORing together arguments ( for example flags or options such as in Win32 (WM_MINIMIZED|WM_TOPMOST|WM_VISIBLE) ) I don't understand how that principle works, how can you combine three values together and then be able to uncombine them. For example lets say WM_MINIMIZED is 01h (or 1), WM_TOPMOST is 10h (2), and WM_VISIBLE is 11h (3), and if i OR them together the final result will be 11h. Which is the same as WM_VISIBLE.


Think them more like flags that are either True(1) or False(0). With OR if any are true then the statement is true. So:

1 | 0 | 1 = 1
0 | 1 | 1 = 1
0 | 0 | 0 = 0

I wouldnt worry about trying to bitwise OR them, unless you really have to for an assigmnent or something. =)

Quote:
So how does the function that i pass these combined options knows that I passed 3 options and not just one WM_VISIBLE?


probably by Variable Length Arguments:

http://www.swig.org/Doc1.3/Varargs.html

You can pass multiple arguments to the same function.
Quote:
probably by Variable Length Arguments:

Nope, the functions in question use bitwise operations as previously observed. The "combined options" are really just a single parameter.
Thanks guys, i made a mistake in my OP, im currently doing assembly so im used to putting "h" at the end of numbers, i obviously meant to put "b" for binary. So basically the flags are meant to be ORed together? Then everything makes sense, I just didn't see how something like 1b, 10b, and 11b can be ORed unambiguously, but turns out they cant be. So i just have to use numbers that are a power of 2? Thanks for replies =D

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

This topic is closed to new replies.

Advertisement