Sign in to follow this  
VanillaSnake21

ORing arguments together

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
<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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 ...;
}


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this