bitmask enumeration?

hi, I am learning about formatted I/O, and really struggling to follow what my book is talking about. It says that fmtflags is a bitmask enumeration. I dont really know what that is, but I know what an enum is. But then in the code it done this

1
2
3
ios::fmtflags f;

f = cout.flags();


so that really confused me, because I assumed fmtflags was an emun and f was declared a variable of that enum, but then how could that equate to cout.flags() . So is a bitmask enumeration different from the normal enumeration, where ints basically have strings instead? (Sorry about lack of technical explanation of the enum, have not been learning long).

I understand the point in the flags i believe, it is changing how the data is formatted, its mostly what the fmtflags actually is, and the bitmask enum that I am really lost with.
Being bit flags means you can use bitwise or to select them.
See https://en.cppreference.com/w/cpp/io/ios_base/fmtflags
I still really dont understand. Is fmtflags a normal enum? If so, why can i set that to equal a function? f = cout.flags() ?
Is fmtflags a normal enum?
It is not really relevant.

If so, why can i set that to equal a function?
It is not set equal to a function. The result of the function (no matter whether it is enum or not) is stored in the variable f.

The values of fmtflags are chosen so that you can combine them with binary operators like | & and it results in a distinct value. See (Bitwise operators):

http://www.cplusplus.com/doc/tutorial/operators/
http://www.cplusplus.com/doc/hex/
ios::fmtflags type is an int. It is used as a bit mask. It is not an enum. From std::

1
2
3
4
5
6
7
8
9
static constexpr _Fmtflags skipws     = static_cast<_Fmtflags>(0x0001);
static constexpr _Fmtflags unitbuf    = static_cast<_Fmtflags>(0x0002);
static constexpr _Fmtflags uppercase  = static_cast<_Fmtflags>(0x0004);
static constexpr _Fmtflags showbase   = static_cast<_Fmtflags>(0x0008);
static constexpr _Fmtflags showpoint  = static_cast<_Fmtflags>(0x0010);
static constexpr _Fmtflags showpos    = static_cast<_Fmtflags>(0x0020);
static constexpr _Fmtflags left       = static_cast<_Fmtflags>(0x0040);
static constexpr _Fmtflags right      = static_cast<_Fmtflags>(0x0080);
....


So to test if say skipws is set,

if (f & skipws)

will only be true if bit 0 is set (irrespective of any of the other bits). Think of f as binary bits with each bit meaning something. Don't think of it as a number - just bits.
Last edited on
ok, i may be understanding a bit better. But I just want to clarify something first. My book says " the ios class declares a bitmask enumeration called fmtflags" I took that to mean, that all those flags, skipws, unitbuf, oct, etc were declared in an enum called fmtflags. Something like

 
 enum fmtflags { skipws, unitbuf, oct, etc}


But, am I misunderstanding that then?

seeplus, My book has not covered bitmasks, but I have watched a few youtube videos (unfortunately, there arent many). in your example, f would be a bitmask, something like 0000 0001, and would be added to skipws (0000 0001), and so when those are & together it would be 0000 0001 therefore true as you say. Am I understanding?

What book are you using?

For bit masks, see https://www.learncpp.com/cpp-tutorial/bit-manipulation-with-bitwise-operators-and-bit-masks/

were declared in an enum called fmtflags. But, am I misunderstanding that then?


Yes.

something like 0000 0001, and would be added to skipws (0000 0001), and so when those are & together it would be 0000 0001 therefore true as you say. Am I understanding?


& isn't add - its bitwise and. The values aren't added.
A book called c++ a beginners guide, by herbert schildt.

Sorry I know its not the normal add, bad phrasing, i meant the bitwise add. I thought for your example if (f & skipws), it would be something like

0000 0001 &
0000 0001
---- -----
0000 0001 and then since the last 1 is on, it is set?
0000 0001 &
0000 0001
---- -----
0000 0001


What you describe is actually bitwise AND.

More bitwise AND:

0000 0001 &
0000 0000
---- -----
0000 0000



Bitwise OR:

0000 0001 |
0000 0000
---- -----
0000 0001


Bitwise Exclusive OR:


0101 0101 ^
0000 0000
---- -----
0101 0101



0101 0101 ^
1111 1111
---- -----
1010 1010
Last edited on
What you describe is actually bitwise AND.


ah yes, this is what I meant, AND, not add. apologies.
Ok so I understand what bitmasks are now, so are bitmask enumerations just enums with bitmasks? And just to double check are these flags, showcase, showpos, skipws etc, bitmasks?

don't overthink it.
its just an enum making constants that are the powers of 2 (from 2^0 to 2^n) eg 1,2,4,8,16,32,64,128 is what you need to poke at each bit in a unsigned char / 8 bit.
how would you check the third bit of an 8 bit thing? you say thing & 4 .. but good coding practice says to name constants and avoid magic numbers, so instead its thing & four or thing & the_bit_that_turns_led_on or whatever word you want to stand in for the constant 4.

I think you know this --- but are thinking on it too hard.

I think you know this --- but are thinking on it too hard.
.

Most definitely lol. But unless I fully understand how something works and can picture it in my head, I will forget it in a few days.
Another example, maybe it'll help:
Imagine you had light that shines red, green, and blue light together.
You could map this as 3-bit binary number, {R, G, B}.
- binary 111 would mean "all components are shining".
- binary 100 would mean "only red is shining"
- binary 011 would mean "green and blue are shining"

If you had some variable that contained the state of this light, you would have the 3-bit {RGB},
where R, G, and B could either be a 0 or a 1.
RGB & 000 = 000
RGB & 001 = 00B
RGB & 010 = 0G0
RGB & 100 = R00
RGB & 011 = 0GB
RGB & 111 = RGB 


So you could check if the green light is on by doing:
1
2
3
4
if (RGB_value & 0b010)
{
    print("green is on!")
}

But instead of writing 0b010 or 2, we can write it as "GreenComponent" or something of that nature, as jonnin mentioned.
1
2
3
4
if (RGB_value & GreenComponent)
{
    print("green is on!")
}


1
2
3
4
5
int WhiteLight = RedComponent | GreenComponent | BlueComponent;
if (rgb_value & WhiteLight == WhiteLight)
{
    print("All three components are on!")
}


_______________________

fmtflags work the same way. Each "atomic" component is a perfect power of 2, and you can combine flags together with | (bitwise OR), and test for a specific flag being enabled with & (bitwise AND).
Last edited on
A book called c++ a beginners guide, by herbert schildt.


The latest version (2nd edition) was published 2003 - so just covers C++98. The C++ language has evolved enormously since then. The current standard is C++20. You'd be better off ditching it and getting a much more up-to-date C++ book - or look at the www.learncpp.com site.
This is how it works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

using namespace std;

int main()
{
    // Turn on showpos and scientific flags
    cout.setf(ios::showpos); // shows sign
    cout.setf(ios::scientific); // scientific notation
    cout << 123 << " " << -456.789 << '\n';
    
    
    // Turn on both showpos and scientific flags
    cout.setf(ios::showpos | ios::scientific); // shows sign and scientific notation together
    cout << 123 << " " << -456.789 << '\n';
    
    return 0;
}



+123 -4.567890e+02
+123 -4.567890e+02
Program ended with exit code: 0



Forget about enumerations, the (actually hidden in <ios>) values behind the flags and bitwise stuff. It's all irrelevant. The flags are just values/parameters you use in the setf() function to control the stream, cout in the case I have shown. The stream could be a file stream to add data to a text file ...

They've tried to make it easy by giving the parameters meaningful names. And the setf() function knows how to use them. :)

ios::showpos is a format flag, it is part of the ios namespace hence the ios:: prefix
showpos when it is set just 'tells' the stream to show the sign (+ or -)

scientific is another format flag (instruction if you like) to put the value in the stream (cout) using scientific notation

There is a list of all the possible flags that can be used as parameters in the setf() function. You can set the flags separately or have a selection by using '|' between each one as I have shown.


FWIW The books not too bad at all by the look of it.
Last edited on
Topic archived. No new replies allowed.