Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about creating a struct of flags in c++

0 views
Skip to first unread message

Pliss...@gmail.com

unread,
Oct 30, 2008, 12:07:04 AM10/30/08
to
Is there an efficient way to create a struct of flag in C++?

I need to create a struct of boolean flag, like this:
struct testStruct {
bool flag1;
bool flag2;
bool flag3;
bool flag4;
bool flag5;
bool flag6;
bool flag7;
bool flag8;
bool flag9;
bool flag10;
bool flag11;
bool flag12;
bool flag13;
};

But if I do that, i print out the sizeof(), that struct and it is 13.
So i think the compile use 1 byte for each flag.

Is it possible to create a struct so that each flag uses only 1 bit.

Thank you.

Victor Bazarov

unread,
Oct 30, 2008, 12:10:47 AM10/30/08
to

Yes, read about bitfields. The syntax is the colon and the field width
after the name of the member, like

bool flag1:1;

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Pliss...@gmail.com

unread,
Oct 30, 2008, 1:50:27 AM10/30/08
to
On Oct 29, 11:10 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:

Thank you Victor.

I am going to follow you suggestion. If I create a class like this:
class myMask {
public:
bool flag1:1;
bool flag2:1;
bool flag3:1;
bool flag4:1;
bool flag5:1;
bool flag6:1;
bool flag7:1;
bool flag8:1;
bool flag9:1;
bool flag10:1;
bool flag11:1;
bool flag12:1;
bool flag13:1;
};

Can I set all the flag to 0 by doing this:

myMask mask;

memset(&mask, '\0', sizeof(myMask));

And can I compare if 2 masks are the same by doing this:

myMask mask1;
myMask mask2;

memcmp(&mask1, &mask2, sizeof(myMask));

Thanks.

Hisense

unread,
Oct 30, 2008, 4:07:09 AM10/30/08
to
On 10月30日, 下午1时50分, "Plisske...@gmail.com" <Plisske...@gmail.com>
wrote:
> Thanks.- 隐藏被引用文字 -
>
> - 显示引用的文字 -

there are two things to say:
1, you need no class, but struct, because struct is good enough to
solve it;
2, either class or struct, you could use ctor where all the bit fields
are set to 0 or any value you want.

anon

unread,
Oct 30, 2008, 8:41:31 AM10/30/08
to
Hisense wrote:
>>
>> I am going to follow you suggestion. If I create a class like this:
>> class myMask {
>> public:
>> bool flag1:1;
>> bool flag2:1;
>> bool flag3:1;
>> bool flag4:1;
>> bool flag5:1;
>> bool flag6:1;
>> bool flag7:1;
>> bool flag8:1;
>> bool flag9:1;
>> bool flag10:1;
>> bool flag11:1;
>> bool flag12:1;
>> bool flag13:1;
>> };
>>
>> Can I set all the flag to 0 by doing this:
>>
>> myMask mask;
>>
>> memset(&mask, '\0', sizeof(myMask));
>>

Proper way is:

myMask mask = myMask();

>> And can I compare if 2 masks are the same by doing this:
>>
>> myMask mask1;
>> myMask mask2;
>>
>> memcmp(&mask1, &mask2, sizeof(myMask));

No, because of padding, some bits can be left uninitialized, therefore
you have to compare each field.
I am not sure if you can do this (probably not)
if(mask1 == mask2)
{
...
}

> 2, either class or struct, you could use ctor where all the bit fields
> are set to 0 or any value you want.

POD structures can not have constructors. Read here:
http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html

James Kanze

unread,
Oct 30, 2008, 10:14:13 AM10/30/08
to
On Oct 30, 6:50 am, "Plisske...@gmail.com" <Plisske...@gmail.com>
wrote:

Victor Bazarov

unread,
Oct 30, 2008, 10:22:21 AM10/30/08
to
Pliss...@gmail.com wrote:
> [..] If I create a class like this:

> class myMask {
> public:
> bool flag1:1;
> bool flag2:1;
> bool flag3:1;
> bool flag4:1;
> bool flag5:1;
> bool flag6:1;
> bool flag7:1;
> bool flag8:1;
> bool flag9:1;
> bool flag10:1;
> bool flag11:1;
> bool flag12:1;
> bool flag13:1;
> };
>
> Can I set all the flag to 0 by doing this:
>
> myMask mask;

That will leave them undefined. Consider defining the default
constructor and the comparison operator.

>
> memset(&mask, '\0', sizeof(myMask));
>
> And can I compare if 2 masks are the same by doing this:
>
> myMask mask1;
> myMask mask2;
>
> memcmp(&mask1, &mask2, sizeof(myMask));

It is better to have the overloaded operator== in your class.

Pliss...@gmail.com

unread,
Oct 30, 2008, 11:03:09 AM10/30/08
to
On Oct 30, 9:22 am, Victor Bazarov <v.Abaza...@comAcast.net> wrote:

Thank you for all the help.

In my case, I have this class which only have
~200 boolean flags. I am thinking if there is a faster way to
* initialize all of them to false
* compare if 2 classes have the same values (the same set of flags are
set)

Thank you again.

.rhavin grobert

unread,
Oct 30, 2008, 11:03:57 AM10/30/08
to
On 30 Okt., 06:50, "Plisske...@gmail.com" <Plisske...@gmail.com>
wrote:

try this:

struct myMask {
union {
unsigned int nMask;
struct {


bool flag1:1;
bool flag2:1;
bool flag3:1;
bool flag4:1;
bool flag5:1;
bool flag6:1;
bool flag7:1;
bool flag8:1;
bool flag9:1;
bool flag10:1;
bool flag11:1;
bool flag12:1;
bool flag13:1;
};

};
};

inline bool operator==(myMask const& rm, myMask const& lm)
{return rm.nMask == lm.nMask;};

the union will force your compiler to put all the bits into one int.
you can the set the int to 0 to clear all bits and compare the ints to
compare the masks.

Just a hint: you'll never need '/0'. just write 0. '/0' is just used
to inform the readers of your code: "hey folks, this is explicitely
meant as a char in a string". so if you want to do something weired:

int i = 20;
while (i-->'\0')
{
if (i == '/2')
{
CallSomeMessageFunc("I've reached 2!");
}
}

.rhavin grobert

unread,
Oct 30, 2008, 11:06:49 AM10/30/08
to

typo: " if (i == '/2') " should be " if (i == '\2') "

sean_in...@yahoo.com

unread,
Oct 30, 2008, 12:24:57 PM10/30/08
to

It's not exactly on point, but you might be
interested in this article about doing
efficient, typesafe bit-twiddling
with C++: http://accu.org/index.php/journals/281

Sean

Victor Bazarov

unread,
Oct 30, 2008, 1:26:02 PM10/30/08
to

What you could do is have a static object of the same class that you'll
use as the prototype for initialising, and have the proper padding to
ensure that all data members are initialised:

struct myLargeClass {
bool blah : 1; // 1st bit
bool clah : 1; // 2nd bit
...
bool zlah : 1; // 25th bit
unsigned padding : 7; // to bring it to 32 bits total

static myLargeClass prototype;
myLargeClass() {
if (this != &prototype)
memset(this, &prototype, sizeof *this);
}
};

Statics are always zero-initialised, so 'prototype' is going to contain
all zeros. Then you can always compare objects using 'memcmp' since
there will be no uninitialised bits.

Don't forget to define 'prototype' somewhere in your implementation file.

Pliss...@gmail.com

unread,
Oct 30, 2008, 2:22:29 PM10/30/08
to

Thank you for this great idea.
I have 2 questions:
1. Do I have to pad it to a multiple of 32?
If I have 153 bool flags, do I pad it with 25 bits? 153 - (32 * 4) =
25

2. I don't understand "what is define 'prototype' somewhere in your
implementation file"?
Isn't it already defined here:
struct myLargeClass {
//...
static myLargeClass prototype;
//...
}

Thank you.

Juha Nieminen

unread,
Oct 30, 2008, 3:18:19 PM10/30/08
to
Victor Bazarov wrote:
> static myLargeClass prototype;
> myLargeClass() {
> if (this != &prototype)
> memset(this, &prototype, sizeof *this);

What's wrong with "*this = prototype;"?

Bo Persson

unread,
Oct 30, 2008, 4:03:09 PM10/30/08
to

*Much* better actually, as the language rules forbid using memset on a
class or struct that has a constructor.


Bo Persson


Victor Bazarov

unread,
Oct 30, 2008, 4:47:31 PM10/30/08
to
Pliss...@gmail.com wrote:
> [..]

> I have 2 questions:
> 1. Do I have to pad it to a multiple of 32?

No. It's up to your platform. You need to find out what the sizeof
yields for your struct with only the used flags there, and then add as
many bitfields as needed.

Essentially, you need to do

unsigned padding : ( sizeof(myLargeClass) * CHAR_BITS - Nflags );

> If I have 153 bool flags, do I pad it with 25 bits? 153 - (32 * 4) =
> 25

If your system wants to create an object with size divisible by 16, say,
you will only need to add 9...

>
> 2. I don't understand "what is define 'prototype' somewhere in your
> implementation file"?
> Isn't it already defined here:
> struct myLargeClass {
> //...
> static myLargeClass prototype;

No, here it's only *declared*. Read up on static data members.

> //...
> }
>
> Thank you.

James Kanze

unread,
Oct 31, 2008, 6:42:26 AM10/31/08
to
On Oct 30, 4:03 pm, "Plisske...@gmail.com" <Plisske...@gmail.com>
wrote:

> > > myMask mask;

> > > memset(&mask, '\0', sizeof(myMask));

> > > myMask mask1;
> > > myMask mask2;

> > > memcmp(&mask1, &mask2, sizeof(myMask));

> In my case, I have this class which only have


> ~200 boolean flags. I am thinking if there is a faster way to
> * initialize all of them to false

Faster than what? I'd expect the compiler to use the fastest
means available on the target hardware for myMask().

> * compare if 2 classes have the same values (the same set of flags are
> set)

Regretfully, there's not real way to compare the values other
than one by one. The compiler is free to introduce padding
where ever it wants. In practice, if you arrange for the total
number of bits to be a multiple of your machine's word size
(with an unsigned pad:n at the end, where n is whatever is
needed), and ensure that the added field is always 0, memcmp
will almost certainly work, even if the standard doesn't
guarantee it.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
Oct 31, 2008, 6:52:49 AM10/31/08
to
On Oct 30, 4:03 pm, ".rhavin grobert" <cl...@yahoo.de> wrote:
> On 30 Okt., 06:50, "Plisske...@gmail.com" <Plisske...@gmail.com>
> wrote:

[...]


> > And can I compare if 2 masks are the same by doing this:

> > myMask mask1;
> > myMask mask2;

> > memcmp(&mask1, &mask2, sizeof(myMask));

> try this:

> struct myMask {
> union {
> unsigned int nMask;
> struct {
> bool flag1:1;
> bool flag2:1;
> bool flag3:1;
> bool flag4:1;
> bool flag5:1;
> bool flag6:1;
> bool flag7:1;
> bool flag8:1;
> bool flag9:1;
> bool flag10:1;
> bool flag11:1;
> bool flag12:1;
> bool flag13:1;
> };
> };
> };

> inline bool operator==(myMask const& rm, myMask const& lm)
> {return rm.nMask == lm.nMask;};

Lot's of problems with that.

-- It's not legal C++. Only unions can be anonymous, not
structs.

-- You'll almost certainly end up with undefined behavior using
it; you can't access the nMask element unless it was the
last one written to.

-- If you've written to the flags structure (which you haven't
named), the padding bits may take on any arbitrary values.
Which mean that two equal myMask may have unequald nMask.

-- For up to 16 flags, you're OK, but for more, the unsigned
may be smaller than the struct.

> the union will force your compiler to put all the bits into
> one int.

Not really.

> you can the set the int to 0 to clear all bits and compare the
> ints to compare the masks.

If the int is large enough, this will probably work *IF* he
makes sure that any unused bits in the struct are always 0.

Hendrik Schober

unread,
Oct 31, 2008, 7:44:16 AM10/31/08
to

While this works, I wonder what's wrong with 'std::bitset'
that you prefer to do it manually? (I have never used it,
so I don't know what its disadvantages are.)

> V

Schobi

Pliss...@gmail.com

unread,
Nov 1, 2008, 4:11:15 PM11/1/08
to

Thank you for all the response on this thread.

I have 1 more question.
With this idea, I can use 'memset' to clear all the flags in the
structs.
And I can use 'memcmp' to compare flags in 2 different structs.

What can I do to 'OR' the 2 structs of flags?
I know i can do this for each flag of struct:
s1.flag1 |= s2.flag1;
s1.flag2 |= s2.flag2;
s1.flag3 |= s2.flag3;

But is there a better way?

Thank you.


Victor Bazarov

unread,
Nov 2, 2008, 9:31:46 AM11/2/08
to
Pliss...@gmail.com wrote:
> [..]

> I have 1 more question.
> With this idea, I can use 'memset' to clear all the flags in the
> structs.

You're better off just assigning from a prototype. 'memset' is
not the best solution.

> And I can use 'memcmp' to compare flags in 2 different structs.
>
> What can I do to 'OR' the 2 structs of flags?
> I know i can do this for each flag of struct:
> s1.flag1 |= s2.flag1;
> s1.flag2 |= s2.flag2;
> s1.flag3 |= s2.flag3;
>
> But is there a better way?

I don't know of any. With bitfields like you want, you will
probably have to change them manually like this. Don't yield
to the temptation to use a union. There was a suggestion to
use a bitset instead, take it into cosideration.

0 new messages