L
lithiumcat
Hi,
This question seems to come up quite often, however I haven't managed
to find an answer relevant to my case.
I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;
These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.
I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;
My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in it.
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.
Could you please help me choosing between the two methods?
Thanks in advance.
This question seems to come up quite often, however I haven't managed
to find an answer relevant to my case.
I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;
These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.
I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;
My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in it.
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.
Could you please help me choosing between the two methods?
Thanks in advance.