# 3.8a — Bit flags and bit masks

Note: This is a tough lesson. If you find yourself stuck, you can safely skip this lesson and come back to it later.

Bit flags

Using a whole byte to store a boolean leaves 7 of the 8 bits unused. While this generally is fine, in storage-intensive cases where we have lots of related boolean options, it can be useful to “pack” 8 individual booleans into a single byte for storage efficiency purposes. These individual bits are called bit flags. Since the bits can’t be accessed directly, we have to use the bitwise operators to set, clear, or query them.

Note: We use hexadecimal numbers in this lesson. If you need a refresher on hexadecimal numbers, we discuss hex in lesson 2.8 -- Literals.

For example:

To query a bit state, we use bitwise AND:

To set a bit (turn on), we use bitwise OR:

To clear a bit (turn off), we use bitwise AND with an inverse bit pattern:

To toggle a bit state, we use bitwise XOR:

As a real-life example, in OpenGL (a 3d graphics library), some functions take one or more bit flags as a parameter:

GL_COLOR_BUFFER_BIT and GL_DEPTH_BUFFER_BIT are defined as follows (in gl2.h):

Here’s a small example:

Why are bit flags useful?

Astute readers will note that the above myflags example actually doesn’t save any memory. 8 booleans would normally take 8 bytes. But the above example uses 9 bytes (8 bytes to define the options, and 1 bytes for the bit flag)! So why would you actually want to use bit flags?

Bit flags are typically used in two cases:

1) When you have many sets of identical bitflags.

Instead of a single myflags variable, consider the case where you have two myflags variables: myflags1 and myflags2, each of which can store 8 options. If you defined these as two separate sets of booleans, you’d need 16 booleans, and thus 16 bytes. However, using bit flags, the memory cost is only 10 (8 bytes to define the options, and 1 byte for each myflags variable). With 100 myflag variables, your memory cost would be 108 bytes instead of 800. The more identical variables you need, the more substantial your memory savings.

Let’s take a look at a more concrete example. Imagine you’re creating a game where there are monsters for the player to fight. When a monster is created, it may be resistant to certain types of attacks (chosen at random). The different type of attacks in the game are: poison, lightning, fire, cold, theft, acid, paralysis, and blindness.

In order to track which types of attacks the monster is resistant to, we can use one boolean value per resistance (per monster). That’s 8 booleans per monster.

With 100 monsters, that would take 800 boolean variables, using 800 bytes of memory.

However, using bit flags:

Using bit flags, we only need one byte to store the resistances for a single monster, plus a one-time setup fee of 8 bytes for the options.

With 100 monsters, that would take 108 bytes total, or approximately 8 times less memory.

For most programs, the amount of memory using bit flags saved is not worth the added complexity. But in programs where there are tens of thousands or even millions of similar objects, using bit flags can reduce memory use substantially. It’s a useful optimization to have in your toolkit if you need it.

2) Imagine you had a function that could take any combination of 32 different options. One way to write that function would be to use 32 individual boolean parameters:

Hopefully you’d give your parameters more descriptive names, but the point here is to show you how obnoxiously long the parameter list is.

Then when you wanted to call the function with options 10 and 32 set to true, you’d have to do so like this:

This is ridiculously difficult to read (is that option 9, 10, or 11 that’s set to true?), and also means you have to remember which parameters corresponds to which option (is setting the edit flag the 9th, 10th, or 11th parameter?) It may also not be very performant, as every function call has to copy 32 booleans from the caller to the function.

Instead, if you defined the function using bit flags like this:

Then you could use bit flags to pass in only the options you wanted:

Not only is this much more readable, it’s likely to be more performant as well, since it only involves 2 operations (one bitwise OR and one parameter copy).

This is one of the reasons OpenGL opted to use bitflag parameters instead of many consecutive booleans.

Also, if you have unused bit flags and need to add options later, you can just define the bit flag. There’s no need to change the function prototype, which is good for backwards compatibility.

An introduction to std::bitset

All of this bit flipping is exhausting, isn’t it? Fortunately, the C++ standard library comes with functionality called std::bitset that helps us manage bit flags.

To create a std::bitset, you need to include the bitset header, and then define a std::bitset variable indicating how many bits are needed. The number of bits must be a compile time constant.

If desired, the bitset can be initialized with an initial set of values:

Note that our initialization value is interpreted as binary. Since we pass in the value 3, the std::bitset will start with the binary value for 3 (0000 0011).

std::bitset provides 4 key functions:

• test() allows us to query whether a bit is a 0 or 1
• set() allows us to turn a bit on (this will do nothing if the bit is already on)
• reset() allows us to turn a bit off (this will do nothing if the bit is already off)
• flip() allows us to flip a bit from a 0 to a 1 or vice versa

Each of these functions takes a bit-position parameter indicating which bit should be operated on. The position of the rightmost bit is 0, increasing with each successive bit to the left. Giving descriptive names to the bit indices can be useful here (either by assigning them to const variables, or using enums, which we’ll introduce in the next chapter).

This prints:

```Bit 4 has value: 1
Bit 5 has value: 0
All the bits: 00010010
```

Note that sending the bitset variable to std::cout prints the value of all the bits in the bitset.

Remember that the initialization value for a bitset is treated as binary, whereas the bitset functions use bit positions!

std::bitset also supports the standard bit operators (operator|, operator&, and operator^), so you can still use those if you wish (they can be useful when setting or querying multiple bits at once).

We recommend using std::bitset instead of doing all the bit operations manually, as bitset is more convenient and less error prone.

The principles for bit flags can be extended to turn on, turn off, toggle, or query multiple bits at once, in a bit single operation. When we bundle individual bits together for the purpose of modifying them as a group, this is called a bit mask.

Let’s take a look at a sample program using bit masks. In the following program, we ask the user to enter a number. We then use a bit mask to keep only the low 4 bits, which we print the value of.

```Enter an integer: 151
The 4 low bits have value: 7
```

151 is 1001 0111 in binary. lowMask is 0000 1111 in 8-bit binary. 1001 0111 & 0000 1111 = 0000 0111, which is 7 decimal.

Although this example is pretty contrived, the important thing to note is that we modified multiple bits in one operation!

An RGBA color example

Now lets take a look at a more complicated example.

Color display devices such as TVs and monitors are composed of millions of pixels, each of which can display a dot of color. The dot of color is composed from three beams of light: one red, one green, and one blue (RGB). By varying the intensity of the colors, any color on the color spectrum can be made. Typically, the amount of R, G, and B for a given pixel is represented by an 8-bit unsigned integer. For example, a red pixel would have R=255, G=0, B=0. A purple pixel would have R=255, G=0, B=255. A medium-grey pixel would have R=127, G=127, B=127.

When assigning color values to a pixel, in addition to R, G, and B, a 4th value called A is often used. “A” stands for “alpha”, and it controls how transparent the color is. If A=0, the color is fully transparent. If A=255, the color is opaque.

R, G, B, and A are normally stored as a single 32-bit integer, with 8 bits used for each component:

 32-bit RGBA value bits 31-24 bits 23-16 bits 15-8 bits 7-0 RRRRRRRR GGGGGGGG BBBBBBBB AAAAAAAA red green blue alpha

The following program asks the user to enter a 32-bit hexadecimal value, and then extracts the 8-bit color values for R, G, B, and A.

This produces the output:

```Enter a 32-bit RGBA color value in hexadecimal (e.g. FF7F3300): FF7F3300
255 of 255 red
127 of 255 green
51 of 255 blue
0 of 255 alpha
```

In the above program, we use a bitwise AND to query the set of 8 bits we’re interested in, and then we right shift them to move them to the range of 0-255 for storage and printing.

Note: RGBA is sometimes stored as ARGB instead, with the alpha channel being stored in the most significant byte rather than the least significant.

Summary

Summarizing how to set, clear, toggle, and query bit flags:

To query bit states, we use bitwise AND:

To set bits (turn on), we use bitwise OR:

To clear bits (turn off), we use bitwise AND with an inverse bit pattern:

To toggle bit states, we use bitwise XOR:

Quiz

1) Given the following program:

1a) Write a line of code to set the article as viewed.
1b) Write a line of code to check if the article was deleted.
1c) Write a line of code to clear the article as a favorite.
1d) Extra credit: why are the following two lines identical?

 3.x -- Chapter 3 comprehensive quiz Index 3.8 -- Bitwise operators

• AMG

Alex,
1) Would suggest initialization: ‘unsigned char myArticleFlags (0x0);’
2) Why copy initialization is preferred over direct and uniform initialization. ‘unsigned char option_viewed = 0x01;’ instead of ‘unsigned char option_viewed {0x01};’

• Alex

1) Done.
2) It’s not. When initializing fundamental variables, any of the three initialization methods is fine. I tend to use copy initialization just out of habit.

• JoeyM

Using C++11 would the following code now be

• Hardik

it’s output is as follows :-
1
2
4
8
16
32
64
128

Does this signify that the whole byte is occupied instead of alloting each byte to a single char variable(options) ? Have u given each bye to single char option or a single bit has been alloted to each of the char variable?

• Hardik

sorry…i meant that it is alloted a single byte to each of the char variable or a whole byte has been alloted to all of the options as a whole using bit flags ?

• Alex

Variable “me” is a char, which takes a whole byte. The flags also take an entire byte each. In the above code, you’re doing a bitwise AND on “me” and the flag, resulting in a new byte with the appropriate bits set, which is then being interpreted as an integer (since chars are integers)

• Hardik

i understood that.Thank You. BUT, Then, How does bit flags save memory ?
Plz Explain it to Me ! i always get stuck in this chapter….!!!

• Alex

If you only have one set of states you’re tracking, it doesn’t save any memory. In the example above, we end up using 9 bytes (8 bytes to define the bit flags and 1 byte to store them), as opposed to using 8 bytes if we just used a single boolean to store each state.

However, if you have multiple objects that you need to store states for, then bit flags start yielding benefits. Let’s say you want to store a set of states for both yourself and your evil twin. Using booleans, you’d need 2 full sets of booleans (2 x 8 booleans), which would be 16 bytes. However, with bit flags, it would only cost 10 bytes (8 bytes to define the bit flags, and 1 byte per object to store the bits). So we’re already seeing savings. Those savings continue to increase with additional objects.

• Hardik kalra

But How? Without using bit flags also it would end up using 10 bytes….Cant The Second variable(me1) access the same options as it was accessed by the first variable(me) ?

And One More Help From You…..
Plz Define A Set Of Options(Like Above) But, That shouldnt Use Bitflags

• Alex

With bit flags, 2 variables (total cost = 10 bytes):

Without bit flags (total cost = 16 bytes):

• Hardik kalra

Thats What I’m asking…..Can’t The Second Variable, that is, eviltwinflags access the meisMad Or Any of the options that have been used for "me" !?

If yes, then see, it will also consume 10bytes only

And One More Question !
When i try to print isMad Or Any Option without printing it like (me & isMad), it prints it as an unrecognizable character……Why?

• Alex

> Can’t The Second Variable, that is, eviltwinflags access the meisMad Or Any of the options that have been used for “me” !?

Yes, it can. That’s why bit flags are useful -- we only need to define the bit flags once, and then we can use them over and over.

The bit flags are printing as funny characters because they’re printing as chars, and chars with values lower than 32 are “unprintable”, so your OS is subbing in some other symbol.

• Hardik kalra

Here, in This Code…
false;
bool meIsHappy = false;
bool meIsLaughing = false;
bool meIsAsleep = false;
bool meIsCrying = false;

bool evilTwinIsHungry = false;
bool evilTwinIsHappy = false;
bool evilTwinIsLaughing = false;
bool evilTwinIsAsleep = false;
bool evilTwinIsCrying = false;

Can the eviltwinflags access the options that have been used for "me" !? I meant to ask this !

For Eg. evil twin flags |= meIsMad | meIsHungry; //initial value of evil twin flags was zero

• Alex

> Can the eviltwinflags access the options that have been used for “me” !?

In the bit flags case, yes. In the boolean case, no.

This is fine if meIsMad and meIsHungry are bit flags. This is not fine if they are booleans. The difference is that the bit flags don’t actually hold any values -- they’re just bit position indicators. So they can be shared. The variable that holds the actual values (for me and my evil twin) needs to be unique, and can’t be shared.

• Hardik

Don’t you think when we do (myflags & option4) it evaluates to ZERO, so how does it query the bit state, or, here, & is an overloaded operator ?

• Alex

I’m not sure I understand the question. myflags & option4 causes operator & to evaluate operands myflags and option4 to produce a bitwise result. It may evaluate to zero or non-zero depending on the value of myflags.

• Hardik

And I think all the bitwise operators are overloaded when u use them to turn on, off, toggle or query their state !
am I right or not? Plz tell me !

• Alex

No, they’re not overloaded in this context.

• Hardik kalra

So If I try to assign boolean values to evil twin flags….will it give an error ?

• Alex

Probably not, since booleans can be converted to chars or other integers. It just won’t do what you want.

• Hardik kalra

Thats what i meant to say :-
bool meIsHungry = false;
bool meIsHappy = false;
bool meIsLaughing = false;
bool meIsAsleep = false;
bool meIsCrying = false;

bool evilTwinIsHungry = false;
bool evilTwinIsHappy = false;
bool evilTwinIsLaughing = false;
bool evilTwinIsAsleep = false;
bool evilTwinIsCrying = false;

Inspite of using 2 sets of booleans for two vars we can just use one set for two variables….i aint talking about modifications here

Same memory would be saved
(8bytes + 2bytes) = 10Bytes would be used

• Alex

No. Each boolean represents a specific piece of memory that we’re using to store a value. That can’t be shared between two variables.

• Hardik kalra

And If We Try To Use Integers !?

• Alex

Doesn’t matter. You seem to be missing some fundamental points, so let me try one last time to see if I can make this clear. From the beginning.

In order to store a value (of any type) we need a variable to do so.

If order to store 2 values, we need 2 variables:

We can’t use the same variable to hold two (or more) independent values, because as soon as we assign the variable a second value, it will lose its first value (and vice-versa). We need independent memory locations to hold independent values.

Now consider the case where we want to store 8 independent boolean values:

Because these need to be separate values, we have to use 8 boolean variables. If we needed two sets of these, we’d need 16 boolean variables.

This works, but in the case of bool it’s a waste of memory. Because machines tend to be byte-addressable, a bool takes 1 byte (8 bits). But only 1 of those bits is actually used to store true or false -- the 7 bits go to waste.

If only there were some way to use those other 7 bits. There is -- bitwise operators. By being clever with the bitwise operators, we can get and set the individual bits in a byte, which allows us to compact 8 unique boolean values into a single byte. For our single byte, we typically use an unsigned char.

But in order to do this, we need to be able to identify each bit individually. We typically say a byte is 8 bits, so we can number the bits from left to right: 8 7 6 5 4 3 2 1. Then all we need to do is say: turn bit 5 on, turn bit 4 off, flip the state of bit 2.

The bit numbers are reusable because they’re just bit positions. The unsigned char needs to be unique so we can store a unique set of 8 bits.

Our bit flag variables act as the bit numbers (which is why they are reusable -- they just identify which bit we’re talking about, not the value we’re trying to get or set). The unsigned char (me or my evil twin) act as the variable that stores a unique set of 8 bits.

If you have any minor clarifications needed about this, I’m happy to address. But if you still don’t get it, then I’d say move on. This isn’t critical to know and it won’t block you from proceeding.

• Hardik kalra

So The Conclusion is that we cannot re-assign fundamental data types to two variables but this is not the case with BitFlags…..Ok !

• Hardik kalra

Sorry I Didnt mean to say this…i know that we cannot use one variable to store two values…..this is basic….what i meant to ask is that :-
for eg :-
bool opt1 = false;
bool opt2 = true;

bool sopt1 = false;
bool sopt2 = true;

//Now Lets Declare two char vars :-
unsigned char myflags = !opt1;
unsigned char eviltwinflags = opt2;

See Here There was no requirement to define sopt1&2….that’s what i meant to say that why we are declaring two sets of booleans if our work can be done by just using one set……

Yes I Agree on one point that we can produce an aggregated result using bitwise operators;
For Eg -- myflags |= opt1 | opt2;
(opt1 and opt2 are bit flags here)…..

I Hope Now u have understood my question !

• Alex

You would never do this. You’re mixing metaphors. The top set of 4 booleans is what you’d do without bit flags, since you’re using discrete variables to hold values.

If you’re using bit flags, you need two things: a variable to hold the bits (myflags and eviltwinflags) AND the bit positions. We use symbolic constants to give meaning to the bit flags (e.g. isHappy, because that’s more meaningful than 0x4).

You’d never use booleans as the bit positions because booleans only hold 2 values (0 and 1), which is 1 bit. If you used booleans as bit flags then you’d have no way to access the other 7 bits in your variable.

• Jim Smith

For those of us for whom English is a foreign language it can be a little confusing the sentence "Write a line of code to unset the article as a favorite."

Searching for the meaning of the verb "to unset". I have found that most reputable online dictionaries don’t even recognize this as a verb but only as an adjective with the following meanings:
a) not fixed in a setting, unmounted (e.g. unset diamonds)
b) not firmed or solidified (e.g. unset concrete)

Some sources say that "to unset" means "(label) to make not set" (which is even more confusing). How can I set a bit in such a way as to make it "not set"?

On the other hand, the verb "TO RESET" has a clear meaning in engineering, "to restore (a gauge, dial, etc) to zero". That meaning was borrowed by Computer Science where it means "clear to restore (the contents of a register or similar device) in a computer system to zero".

TLDR unset = reset?

• Alex

In this context, unset = reset. Reset is a bit ambiguous because it’s unclear whether you’re resetting to 0 or resetting to the initial state, whatever that was. So “unset” is sometimes used to mean “return to the off state”.

However, in this context, the word “clear” works just as well, so I’ve replaced “unset” with “clear”, which makes it clear(er) we’re setting bits back to 0.

• Dani

#include <bitset>
#include <iostream>

const int option_1 = 0;
const int option_2 = 1;
const int option_3 = 2;
const int option_4 = 3;
const int option_5 = 4;
const int option_6 = 5;
const int option_7 = 6;
const int option_8 = 7;

int main()
{
std::bitset<8> bits(0x2);
bits.set(option_5);
bits.flip(option_6);
bits.reset(option_6);
std::cout << "Bit 4 has value: " << bits.test(option_5) << ‘\n’;
std::cout << "Bit 5 has value: " << bits.test(option_6) << ‘\n’;
std::cout << "All the bits: " << bits << ‘\n’;
std::cout << "size of bits  " <<sizeof(bits) ;// _________shows 4 byte ____________//

return 0;
}

i have a question ,i guess that size of "bits"(source code above) will need 1 byte( 8 bits) only,after i compiled the code it shows 4 byte.can you explain me ?Thanks for nice tutorial

• Alex

This comes down to how std::bitset is implemented, which may differ from compiler to compiler. But most likely, your version of std::bitset is allocating 32 bits (one word) for anything between 1 and 32 bits for efficiency purposes. This makes the code execute faster at the cost of potentially wasting some memory.

• Dani

Thanks a lot for your explanation,
i got it.

• 0phoff

Hey,

Here you write that this code will use 9bytes (8 for options & 1 for the flag itself), but I’m not entirely agreeing with that.
Because you define the options as being const (and you never use address-of), wouldn’t that allow the compiler to inline the values?
I know the c++ standard doesn’t force compilers to inline const statements, but I think most of them do!
This would mean that, even for situations where you have only a few flags, the way with bits would still take less memory (but more computation time because of the binary operators…)

Let me know if I am right or not! 🙂

• Alex

Maybe I should say, 9 bytes in the worst case. You’re right though, a good compiler would probably inline the const variables, making the code slightly bigger but reducing the memory footprint.

• 0phoff

Would the code be bigger though?
Anyway I am just nitpicking..
And this could be solved with enums and then there is no discussion! 😉

• Alex

Good question, actually. I was thinking about inline functions, which tend to make more code than non-inline functions because the code gets copied into many places instead of staying in a single place. But with literals, at least with fundamental types, this probably isn’t true (it might be for more complex types, like classes).

• Terry

Hi Alex, how come you use | to specify both options 4 and 5 to turn on, wouldn’t it be & because you would be saying option4 AND option 5?

• Alex

No. And in fact, bitwise logic tends to be the opposite of how we use terms in common language. In common language we tend to think of OR as a restriction (you can have “A” or “B”, you’re restricting the choice from a set” and AND as an aggregation (A and B is more than A or B alone).

In bitwise logic, it’s the opposite. OR produces a result that includes all the bits in both operands, so A OR B includes all the bits from both A and B (an aggregation). AND produces a result that includes only the bits in both A or B (a restriction).

This makes sense when you consider things from a bit by bit level, but it does make it a little hard to wrap your head around the first time.

• andy mackay

Just spent half an hour scratching head over the very first example:-

Testing to see if an option is set using bitwise AND
if (myflags & option4)

I was thinking for ages that wouldn’t show if option4 was set as it would give 0000 0000, but it just dawned on me that we are testing if myflags has option option4 set and not checking to see if option4 is set, jeez and can be thick sometimes, lol.

• Victor

Hello again, Alex.

Please could you tell us about bit fields - what they are and how to use them? I hope I’m not asking for too much…

• Alex

Bit fields allow you to create members of a struct that use less that 1 byte each. This can be useful if you want to compact multiple sub-byte members together to save space. However, with the amount of memory modern machines tend to have, bit fields aren’t used near as much these days, so I haven’t written a full lesson on them yet. I’ve added it to my to-do list for the future.

• Victor

Hi Alex and thanks again for this great site.

If one is using std::bitset, is it possible to use typedefs to name custom types rather than having to type out std::bitset<blah> for every declaration, and if so would you consider this good practice?

Thanks.

P.S.: How do I get my photo to display in comments 🙂 ?

• Alex

Yes, you can use a typedef (or type alias). It’s fine to do this if you want.

To get a photo to display in comments, you need to set up a gravatar with your associated email address. See gravatar.com.

• James Ray

Hi Alex,

After your first example, it may be helpful to post a link to the tutorial on literals. I had to go back as I forgot that hexadecimal counts as 0-9, then A-F in one digit, to go up to 15. I went back because I wanted to check how one digit would go past 9.

• James Ray

Oh, I see that you already had a link to section 2.8 -- literals, later on. Maybe it’s better to put it straight after when it comes up first in the tutorial after the first example?

• Alex

Good call. I’ve added a note to the lesson. Thank you.

• vishal

why not just ,me= & isHappy? but me= &~isHappy; I do not understand the purpose of not operator there?

• Alex

Turning a bit on is easy -- we just do a logical OR. Turning a bit off is a little more difficult, since C++ doesn’t have a logical operator that maps directly to that behavior. So instead, we have to combine two logical operators to get the desired effect.

Consider the statement me &= ~isHappy. We know isHappy has value 0000 1000, so ~isHappy has value 1111 0111. We don’t know what value “me” could have, it could be anything. So let’s just say the bits are represented by the letters abcd efgh. Our statement is now abcd efgh &= 1111 0111.

For any given bit x, if you logical AND x with a 1, x will retain its value. If you logical AND x with a 0, x will be turned off. By using logical NOT on isHappy, we produce exactly the right bit pattern to use with logical AND in order to have all of the bits preserve their original values except the one we want to turn off.

• Igna

Typo… you miss the word " a " before "game" in the following statement "Imagine you’re creating game where there are monsters for the player to fight", I think it should be "Imagine you’re creating a game where there are monsters for the player to fight"

And thanks again for the tutorial…

PD: Sorry about my English but I speak Spanish

• Anonymous

Can the 1a, 1b, 1c questions be solved by using bitset ? And are bitwise operators totally replaceable  with bitset ? Because it’ll be great if everything can be done using bitset.

• Alex

Yes, quiz questions 1a, 1b, and 1c could be solved that way. Variable myArticleFlags could be a std::bitset and the quiz code should still work (since std::bitset supports bitwise operators).

However, if you’re using std::bitset, you’d want to consider defining the option_xxx values differently (since the bitset functions use indices rather than integer values).

std::bitset is great, particularly if you want to tweak single bits. It doesn’t do quite as well if you need to query or set multiple bits at once.

• Anonymous

Can we query, set, reset multiple bits at once by using bitset ? If so, how ?

• Alex

You can, by using the &, |, and ^ operators. You can not via the set(), reset(), and flip() member functions.

• Eric

Alex,

You’re missing the

at the bottom of the RGBA color example.

Thanks for the great work with these tutorials.

• Alex

Updated, thanks!

• Karlo

Hi, Alex! I have a suggestion when turning off bits:

When you have something like this:

in case we need to modify more options at once, I found it better to use DeMorgan’s law, like this:

This way you keep the consistency of listing multiple options with | operator like with other actions, and it’s slightly more readable. Maybe add that to the lesson? 🙂

Also, thank you very much for these lessons. Very well organized, easy to follow, and most important, under constant maintenance and open to suggestions. Keep it up! 🙂

• Alex

Love it! That’s definitely better than what I had. I’ve added it to the lesson. Much appreciated.

• nikos-13

"  const int option_1 = 0;
const int option_2 = 1;
const int option_3 = 2;
const int option_4 = 3;
const int option_5 = 4;
const int option_6 = 5;
const int option_7 = 6;
const int option_8 = 7;

int main()
{
std::bitset<8> bits(0x2); // we need 8 bits, start with bit pattern 0000 0010  "

That means that our first option will be option_2 ?????

• Alex

Yes, this will start initialized with option_2.

• nikos-13

Thank you Alex!!!

• nikos-13

" Then you could use bit flags to pass in only the options you wanted:

someFunction(option10 | option32); "

In this case, where we have to define our options? at someFunction or main???

• Alex

Good question. In this case, both the caller and callee are going to need access to the options. Probably the best thing to do would be define them at the top of your file (just below the includes) (as global variables, which I cover at the start of chapter 4) or in a header file (which you can then #include).

• nikos-13

"

// Define 8 separate flags (these can represent whatever you want)
// Note: in C++11, better to use "uint8_t" instead of "unsigned char"
const unsigned char option1 = 0x01; // hex for 0000 0001
const unsigned char option2 = 0x02; // hex for 0000 0010
const unsigned char option3 = 0x04; // hex for 0000 0100
const unsigned char option4 = 0x08; // hex for 0000 1000
const unsigned char option5 = 0x10; // hex for 0001 0000
const unsigned char option6 = 0x20; // hex for 0010 0000
const unsigned char option7 = 0x40; // hex for 0100 0000
const unsigned char option8 = 0x80; // hex for 1000 0000

// byte-size value to hold some combination of the above 8 options
unsigned char myflags = 0; // all flags/options turned off to start

"

Could you please show me how to use this in a complete code??? I mean, i understoud how to query,tern on, etc…. but i didn’t understand how to define bit flags….

• Alex

I’ve updated the lesson with an example.

• nikos-13

Thank you very much Alex!!! So, we don’t assign those 8 options, we just define them to use them at the byte-size value right???

• Alex

Right. We define them in such a way that we can use them to isolate single bits within a byte.

• Elruin

In bitset you can also access certain bit by myflags[n], where n is number of bit(from right to left: 0, 1, 2 etc). I think it comes handy in "if" sentences.

• Mike

Presumably there is a danger here if a variable is left un-initialised. For example with the quiz, if

isn’t initialised, I run the risk of starting from some random configuration, don’t I?

• Alex

Yes, absolutely. Presumably you’d want to either initialize myArticleFlags with a value, or assign a value to it shortly after creation.

I’ve updated the quiz question to initialize it to 0.

• Ignacio

You are amazing man!!! I hope you can do a tutorial like this, but oriented to graphical user interfaces, thanks a lot for this amazing material!!!

• bert

Just curious, you say:

"As a side note, different machine architectures may store bytes in a different order. RGBA can be stored as ARGB or BGRA depending on the architecture."

What machine architectures would use that byte ordering?  I’m only familiar with big and little endian.  Granted, it’s been a while, but those orderings don’t strike me as an endian difference.

tx!

• Alex

I think I misspoke -- ARGB is an intentional choice to represent the encoding differently, putting the alpha channel first rather than last. Other permutations (ABGR and BGRA) are the little-endian permutations of RGBA and ARGB.

• Oliver Dawkins

Hi, I am thoroughly enjoying these so far, and I’m learning a lot of the finer points of c++ that I didn’t at University. In the OpenGL example of bitfalgs, why is there a 4 used in the definition?
[#define GL_DEPTH_BUFFER_BIT               0x00000100
#define GL_STENCIL_BUFFER_BIT             0x00000400
#define GL_COLOR_BUFFER_BIT               0x00004000]
I’m struggling to figure out how I would manipulate that/ why it is used. I was also under the impression that any positive number is classed as true(1), so I’m stuck there as well and any enlightenment would be appreciated!

• Alex

These are hexadecimal numbers (you can tell by the 0x suffix), not binary. A hexadecimal digit is 4 bits (0 hex = 0000 binary, 4 hex = 0100 binary). 8 hexadecimal digits of 4 bits each = 32 bits = 4 bytes.

• Dawid

When I check size of (sizeof()) the 8-bits bitflag "bits" (from the example above) i get that it takes 4 bytes. The size of int option_1 is 4 bytes too. Does it mean that I should use fixed width integrers?

• Alex

It would make sense to use fixed width integers for the options, but there isn’t much that you can do about std::bitset<8> taking 4 bytes.

• Jonathan

Is there a way to check that the solutions to the quiz worked correctly? How could I display the state of all the flags at the end of the commands?

• Alex

> Is there a way to check that the solutions to the quiz worked correctly?

Ideally, you’d want to ensure the solutions work with a range of different inputs, and validate that they produce the expected output. You don’t necessarily need to print the state of all the flags, but whether that your set of inputs was converted to the set of expected outputs.

> How could I display the state of all the flags at the end of the commands?

You can use a for loop and logical AND to isolate and print each individual bit. Something like this:

• Luis Alonso

• TJ

Really can’t thank you enough!
This simple tutorial with few examples has done something that no tutorial or book or videoseries has not done before; i finally really understand this topic. It’s not a hard topic, but other tutorials often "overexplain" this. Now i can dive more deep into it, so thanks again!

• Claudio

Great lesson! This is the first tutorial I read in this webpage cause I use another language, but this works for me.

• Travis

Alex,
Obviously I’m missing something here…

If I’m turning on the 0 and 3 spot for the bitset, shouldn’t I get something like 0000 1001 when I print?
You mentioned that you can initialize your bitset with values and that’s what I was trying to accomplish here, but, like I said, I think I’m missing something.

The only way I found to get the results I want is the following:

…I’m prepared for the *facepalm*

• Alex

The fault is probably mine. When you initialize a std::bitset, you don’t use bit positions, you use binary values. So your op4 shouldn’t have value 3 (which is 0000 0011), it should have value 8 (which is 0000 1000).

However, when you use set, flip, and reset, you use bit positions for that. I’ll make that distinction clearer in the lesson.

• David

Hi,
there’s a mistake / typo in the section on bit masks:

1001 0111 & 0000 1111 is NOT 0000 0001 but 0000 0111 (which is, in fact 7 in decimal).

• Alex

Correct, and fixed. Thanks for pointing that out.

• J3ANP3T3R

Question :
in "if (myflags & option4) … // if option4 is set, do something" what if myflags is 1001 1101 ? then to evaluate "if (myflags & option4)" would be

1001 1101 (myflags)
0000 1000 (4)
=
0000 1000

which is true but option4 was set to ON but i just could not get pass the fact that the other bits are also evaluated when we only needed to evaluate bit 4. is there a way to compare the target bit column only ?

• Alex

Remember that memory is only byte-addressible -- this means we can’t directly address individual bits. However, what we can do is cleverly use the bitwise operators to achieve the same effect. Note that option4 has all of the bits it doesn’t care about set to 0. This is so that when we do a bitwise AND (with the entire byte), those bits are guaranteed to resolve to 0, and won’t impact the result. Make sense?

• J3ANP3T3R

Makes perfect sense thanks and that part i got just wondering if there would be a performance issue with having to resolve the zeros with longer binary sets.

• Alex

No, it all gets done in parallel.

• J3ANP3T3R

"unsigned int pixel;
std::cin >> std::hex >> pixel; // std::hex allows us to read in a hex value"

Question : how does C++ know when to convert the input to binary ? or is it binary by default ? pixel is unsinged int and the input is in the form of hex stored to pixel which is unsigned int. i did not see any conversion to binary. is unsigned int a binary type ? thanks 🙂

• Alex

Computer memory is a sequence of binary bits, so everything that goes into memory has to be converted to binary. Most modern CPUs have native handling for converting integers and floating point numbers to binary and back, which makes the conversions very fast.

• Nyap

This is really confusing compared to last lesson D: but i’m going to force myself to take this in before moving to the next lesson

• Nyap

if anybody else is having problems understanding the top section, get a text editor out and go through what each thing does step by step! helped me out a lot

• Alex

What specifically did you find confusing? How can I make this lesson better?

• J3ANP3T3R

that could be the parts with the hex value i think they may need a bit more comment to explain the "how". it encourages the reader to do some digging though so all in all already a better lesson.

• Jane Doe

Ad-Blocker off just for you Alex.

• Peng

Thanks a lot

• Alex

No, because we count bits from 0 to 7, from right to left. So option X is bit X-1. Option 6 is bit 5.

• J

I’d just like to add that [b]std::bitset[/b] plays somewhat nicely with C-style bitfields.  You can use it as an interim to display a bitfield’s individual bits, and for reading in individual bits and turning them into an integer.  Unfortunately, its bitwise operator overloads expect both operands to be bitfields, which can cause problems in situations where we can’t rely on type promotion.

Bitset does bring added convenience, however, in that you can index each bit as if it were an array.

Overall, it’s better to either rely on C-style bitfields (and use bitset if you need I/O to work with individual bits instead of hex values), or rely entirely on bitset and eschew C-style bitfields.  Mixing the two is just opening yourself up to complications.

• Elpidius

Hey Alex, I just found a typo:

"Not only is this much more readable, it’s likely to be more performant as well, since it only involves 2 operations (one logical OR and one parameter copy)."

"logical OR" should say "bitwise OR"

• Alex

Fixed. Thanks for pointing that out.

• Lokesh

I think
“A” standard for “alpha” …
should be
“A” stands for “alpha” …

• Alex

Yup, thanks for pointing out that typo. Fixed!

• Lokesh

@Alex, I found something interesting:
In the std::bitset code example you have used ‘\n’ for newline instead of "\n". It executes fine.
But "\n" consists of two characters -- ‘\'(ASCII code 92) and ‘n'(ASCII code 110).
And since a char variable is represented within single quotes(”), using ‘\n’ is technically wrong.
Also, in windows a newline consumes 2 bytes instead of 1(I created a text file with just a newline, it consumes 2 bytes).
But, after looking at the ASCII table, I found the unprintable ASCII character with code 10(LF- line feed/newline).
Then I defined a new char variable with value 10 like so:
[code]
char new_line = 10;
std::cout << "First line." << new_line << "Second_line" << new_line;
[code]
and it compiled and produced the same output as using ‘\n’.
Thus, my question is: Is the compiler interpreting ‘\n’ or "\n" as LF(ASCII code 10), or is something else going on here?
I understand, this question is far off topic of C++. I was just curious.

• Alex

Yes, the compiler interprets ‘\n’ as ascii code 10 on Windows.

There are other “slash commands” that the compiler interprets listed in lesson 2.7 -- Chars.

• Anonymoose

Generally speaking, a character constant in the form of ‘\c’ is called an escape sequence, and is actually the ASCII or Unicode character represented by that; in this case, the backslash isn’t interpreted as a distinct character, but as a "flag" indicating that the following character or set of characters is an escape sequence.  (This is also why the actual backslash character is represented as ‘\\’.)

Each escape sequence maps to a specific character, with most of them mapping to a character that is either untypeable (such as ‘\n’ for the newline character, ASCII/Unicode 10 (0x0A), as you discovered), or otherwise difficult to represent (such as ‘\'’ for the actual ' character, which would otherwise have to be represented as a raw number instead of a character constant).

• Danny

Hey Alex, I propose that you move this tutorial to another level, probably at the end of procedural programming,just before introducing OOP. Its kinda tough for beginners. It is giving me a hard time trying to capture what is there to get, not knowing where to apply it, difficult syntax……. I don’t know what the problem is.

• Alex

Yeah, this is a tough one. I’ll add a note indicating that this lesson is safe to skip if you get stuck.

Hi, I was wondering of you could explain to me how the following answer you gave would resolve to true were the option deleted?

if (myArticleFlags & option_deleted)

So, to break that down we have (let’s make option_deleted bit 4):

if(???1 ???? & 0001 0000)

Ignoring the if we get a bitwise-AND resulting in:

0001 0000

Surely an if-statement only takes a boolean argument and not a collection of bits?

I am confused

We are left

• Alex

Good question. There’s a few things you need to connect here:
1) If statements execute only if the conditional is boolean true
2) Integers are considered ‘true’ if they are non-zero, and false if they are zero.
3) The integer will be non-zero if any of its bits are set, and zero if none of its bits are set.

Therefore, we can say:

A) If we use an integer as the conditional in an if statement, the if statement will execute if the integer has _any_ non-zero bits.

Now, in our example, we’re doing a logical AND of option_deleted (0x80) and whatever value is in myArticleFlags. There are two outcomes:
A) If myArticleFlags has a 0 for bit 4, then ???0 ???? & 0001 0000 = 0000 0000. All zero bits = integer 0 = boolean false = the if statement doesn’t execute.
B) If myArticleFlags has a 1 for bit 1, then ???1 ???? & 0001 0000 = 0001 0000. Any non-zero bits = integer >0 = boolean true = the if statement executes.

Make sense?

• Shiva

Alex,

I loved the last two modules! These are the sort of things they never taught us at school (and it seems they don’t plan to teach us in college either). Bitwise operations may be outdated, but I feel that these are some of the fine points of a programming language like C++. Are they provided in any other programming language? I haven’t seen them anywhere else.

BTW one thing to note: In the std::bitset example you have used the ‘enum’ datatype, which you haven’t discussed yet as it comes only in a later module. In case you haven’t done this on purpose, you might want to add a note explaining it in brief so that you don’t scare off an unsuspecting reader. 😀

• Alex

Many languages (such as Java and PHP) provide bitwise operators, though they aren’t commonly used.

I removed the enum and replaced it with standard variables for now. Thanks for noticing that.

• Nigel

Alex,  In ‘ Introduction to std::bitset’ you have the enum:

enum BitOptions
{
OPTION_1 = 1,
OPTION_2 = 2,
OPTION_3 = 3,
OPTION_4 = 4,
OPTION_5 = 5,
OPTION_6 = 6,
OPTION_7 = 7,
OPTION_8 = 8
};

Shouldn’t the option values be 0-7?  Your code doesn’t use OPTION_8 but if you do, you get a run time Out-of-Range error.

Thanks for a brilliant set of tutorials!

• Alex

Yes, I messed that up. It should be fixed now. Thanks for noticing!

• Mike

How do you make the pixel example with bitset?
Thanx, amazing tutorials.

• Alex

• Tom

Why do the options for the initial example and for std::bitset refer to different bits? for instance option4:

const unsigned char option4 = 0x08; // hex for 0000 1000

yet

std::bitset<8> bits(0x2); // we need 8 bits, start with bit pattern 0000 0010
bits.set(OPTION_4); // set bit 4 to 1 (now we have 0001 0010)

• Alex

This is due to a difference in the way we’re counting. In the top set of options, we’re counting from 1 (the rightmost bit is 1). std::bitset counts from 0 (the rightmost bit is 0).

• Te Ka

in example from section
"An introduction to std::bitset".
g++ on CentOS7 spits a lot of errors without it

• Alex

Updated. Thanks!

• Phil

The first line requires the namespace std:: while the other three lines don’t. As they are part of the bitset library I thought they would also need the std:: prefix but apparently not. I tried compiling with the prefixes but got an error stating that bits.set, bits.flip  and bits.reset are not part of the namespace "std". Could someone explain why they are not required.

• Alex

std::bitset is a type that is defined inside the std namespace in the bitset header, so it needs the std:: prefix.

bits is a variable name that is defined inside your function, so it doesn’t need a prefix since it’s not inside a namespace.

As for why you don’t need to prefix functions set(), flip(), or reset() with std::, the compiler knows that variable bits is of type std::bitset, so it can infer that functions associated with bits are defined inside the std:: namespace as well.

• Cunni

Huge thanks for these well-crafted tutorials, they have given me the needed traction for c++ programming!

I’m wondering if anyone could give an explanation about what happens if you need more than 8 options:

Would we need an additional byte every time we want this option? I’m not sure I have my head wrapped around what would happen if such situations occur in a parameter list.

• Alex

Good question.

If you need more than 8 options, then you’ll need to use a larger type for both your bitset and your bit flags.

For example:

• Dex

Hi Alex,

I want to say thank you for putting this tutorial. I learned a lot in this material.

I would like to ask why is it needed to flip option4 in your sample code to turn option 4 off:

To turn a bit off, we use bitwise AND with an inverse bit pattern:

As I understand this:

myflags = 0x00 // 00000000
option4 = 0x04 // 00000100

using bitwise AND without flipping option4 will also results in turning option4 off. Is it redundant? This is still bugging me. Thanks in advance.

• Alex

To prove your suggestion doesn’t work, consider the following case where myflags isn’t inintialized to 0:

myflags = 0x14 // 0001 0100

If we AND this with option4, what happens?

myflags = 0x14 // 0001 0100
option4 = 0x04 // 0000 0100

We get 0000 0100.

This means we not only failed to turn off the 4 bit, we also inadvertently turned off the 16 bit.

So clearly doing AND with option4 doesn’t work.

Consider how logical AND works:
If we logical AND bit X with a 1 bit, then bit X keeps its current value regardless of whether bit X is a 1 or 0.
If we logical AND bit X with a 0 bit, then bit X is set to 0 regardless of its initial value.

So, to turn off bit X, we want to make sure that the corresponding bit we’re ANDing is set to 0. We also don’t want to affect any of the other bits, so all the other bits need to be 1s.

So, given some initial value of myflags:
myflags = 0x55 // 0101 0101

To turn just the 4 bit off, we’d want our AND mask to be 1111 1011 (turn off the 4 bit, leave the others alone).

How do we get the bit pattern for 1111 1011? Easy, we invert option4.

• dex

Hi Alex,

Thanks for the reply. I get your point, now I understand it. Thank you so much.

• Mr D

I was really struggling to get my head around this chapter. Then i found a way to print a decimal value as a binary value, which greatly helped with experimenting with and understanding these bitwise operators.

Here’s the code:

• God_Bless_You!

I never lighted bit6! Why It’s up??
What Exactly If(statement calculates?)
1000 1100
& 0010 1100
-----------
0000 1100

So, If(0000 1100)??? // What does this mean? If (What???)

• Alex

Bit 6 isn’t set. 0000 1100 is 12 in binary, and any non-zero number converts to boolean true when used as a conditional. Your output will output if bit 3, 4, OR 6 is set.

If you want to change your output so it prints only when bit 3, 4, AND 6 are set, you could do this:

• God_Bless_You!

Thanks for the hint! Thats what i wanted to do! Only if those bits are on!
I still don’t understand how if(XXXX XXXX & YYYY YYYY) is interpreted though… (in the Assembler)
Keep doing great job Alex!

• Hello

Hi Alex, I want to ask, what does

means? (myflag & option4) Bitwise And I get it. What if statement calculates???
Thanks for all! 😉

• Alex

If option4 has been set in myflag, then the statement after the if statement will execute.

I talk about if statements in section 2.6 -- Boolean values.

• programmer, another one

can we also use this method for question 1C:

• Alex

No.

Using ^= will toggle the state. If it was off, it turns it on. If it was on, it turns it off.

works whether the option was previously favorited or not.

• Kanchana

I really enjoyed your tutorial and learnt C++ entirely from this tutorial about an year ago. And now I’m going through it again with updated lessons. thank you for writing such a grate tutorial. I have wrote ‘C’ codes for micro-controllers. Hence I have some bad feeling about these two points.

a) In ‘Bit Flags’ section we are going save 7 bytes of data using 8 bits of the same byte. but ultimately we have used 9 bytes of data instead of using one byte. I would rather use

will this make things worse?

b) In ‘An RGBA color example’ section, I like to write the code as

because I feel that is much safer. is there any downside? and also need some explanation on

‘unsigned int’ bit-wise and with ‘signed int’ literal, expression results an ‘int’ assigned to a ‘unsigned char’ without a cast. 🙁

I would like to know your opinion on those few questions. thanks again for this valuable tutorial.

-Kanchana

• Alex

1) In general it’s a good idea to stay away from #define macros where you can (this is covered in section 2.9 -- Symbolic constants and the const keyword.

As you’ve noted, using bit-flags for a single variable really doesn’t save anything. Bit-flags typically make more sense when you have hundreds or thousands of variables.

2) Your method works fine. I do mask and shift, you do shift and mask. The end result is the same, and there’s no downside to your method.

Visual Studio doesn’t throw a warning for these, but some other compilers might complain that casting the results of an unsigned int to an unsigned char is potentially dangerous. You could address this by using static_case to let the compiler know this is intentional:

• Elpidius

I would have to agree with Kanchana on the notion of memory. You’ve used 9 bytes instead of 1 byte. Although a const variable shows up in the debugger, using a #define symbolic constant doesn’t take up any memory. If OpenGL used #define symbolic constants, then we can see that #define symbolic constants aren’t all that bad.

Worst-case scenario, the entire program could be written using const variables (for debugging), then all of the const variables could be replaced with #define symbolic constants (for release).

• Alex

Unless you’re pushing the performance limits of your hardware, focusing on memory is probably focusing on the wrong thing. You’re better off focusing on readability, debugability, maintainability, and consistency. Those are much more important than saving a few bytes here and there.

OpenGL was written before some modern best practices were established. Just because a major library doesn’t something doesn’t mean it’s a good idea -- only that it’s possible.

Using different code for debug vs release is a bad idea, and a key way that unintended bugs can creep into your code.

• Kevin Wiggins

I am confused on turning flags on and off. I am new so bare with me.

correct?

so myflags is said to have option 4 and option 5 turned on? 0001 0100 is the bit representation for both options being on?

also is the color example evaluated like this?:

ff7f 3300
ff00 0000
-------
1100 0000
or
ff00 0000

im confused on how 255 came out of that I know hex ff is 255 but how was that resolved from that?

• evan

mate

this is what ff7f3300 is in binary:
1111 1111 0111 1111 0011 0011 0000 0000

and ff000000 is:
1111 1111 0000 0000 0000 0000 0000 0000

• Alex

> so myflags is said to have option 4 and option 5 turned on? 0001 0100 is the bit representation for both options being on?

0001 0100 is the bit representation for option3 and option5 turned on.

As evan said, ff7f3300 in binary is 1111 1111 0111 1111 0011 0011 0000 0000

So when we do this:

We’re taking 1111 1111 0111 1111 0011 0011 0000 0000 and converting it into 1111 1111 0000 0000 0000 0000 0000 0000, then right shifting the bits 24 places, which gives us just 1111 1111. That number is 255 in binary.

• MikeM

Alex, speaking as a guy that has intentionally avoided the concept of bitwise concepts since the dinosaurs roamed I want to say thank you. I get it now. One thing I don’t get is why

I know I will feel like a dolt, but that is the one part I am unclear on here.

• Alex

You’re right, doing the bitwise AND is redundant here, and could be optimized into your second statement.

I intentionally left the redundancy in because I think it’s easier to understand what it’s doing.

• J3ANP3T3R

hey could you leave a small section for a review of what & | &= does or leave a link to the chapters explaining these. i forgot what they are i only remembered && || there maybe new comers like me as well thanks 🙂

also im a bit confused :

“The principles for bit flags can be extended to turn on, turn off, toggle, or query multiple bits at once, in a bit single operation. When we bundle individual bits together for the purpose of modifying them as a group, this is called a bit mask.”

but the example showed different. removing a certain portion of a binary number. how do we manipulate multiple bits at once ?

• Alex

The example does exactly what it says it will do. The user enters a number, let’s say 151, which is 1001 0111 in binary. Then we do a single & operation with lowMask (0000 1111 in binary), which filters out all of the high bits at once (manipulating multiple bits). 1001 0111 & 0000 1111 = 0000 0111, which is 7.