 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Julio M. Merino Vidal Guest
|
Posted: Sun Apr 25, 2004 1:35 am Post subject: Using enum's as bit fields |
|
|
Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
int
main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
return 0;
}
Now, compile it as C and as C++:
[dawn tmp] $ cc -Wall test.c
[dawn tmp] $ c++ -Wall test.c
test.c: In function `int main()':
test.c:12: error: invalid conversion from `int' to `ENUMTEST'
I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
Thanks!
--
Julio M. Merino Vidal
The NetBSD Project - http://www.NetBSD.org/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Sam Holden Guest
|
Posted: Sun Apr 25, 2004 8:33 am Post subject: Re: Using enum's as bit fields |
|
|
On 24 Apr 2004 21:35:53 -0400, Julio M. Merino Vidal <jmmv (AT) menta (DOT) net> wrote:
| Quote: | Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
int
main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
return 0;
}
Now, compile it as C and as C++:
[dawn tmp] $ cc -Wall test.c
[dawn tmp] $ c++ -Wall test.c
test.c: In function `int main()':
test.c:12: error: invalid conversion from `int' to `ENUMTEST'
I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
|
const int bit0 = 1 << 0;
const int bit1 = 1 << 1;
const int bit2 = 1 << 2;
--
Sam Holden
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dhruv Matani Guest
|
Posted: Sun Apr 25, 2004 8:36 am Post subject: Re: Using enum's as bit fields |
|
|
On Sat, 24 Apr 2004 21:35:53 -0400, Julio M. Merino Vidal wrote:
| Quote: | Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
int
main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
|
bit0 | bit2 is NOT a member of the enum.
| Quote: | return 0;
}
Now, compile it as C and as C++:
[dawn tmp] $ cc -Wall test.c
[dawn tmp] $ c++ -Wall test.c
test.c: In function `int main()':
test.c:12: error: invalid conversion from `int' to `ENUMTEST'
I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
|
Use bit-fields as mentioned by the standard:
struct bif_f
{
bit0 : 3;
bit1 : 3;
bit2 : 3;
};
--
Regards,
-Dhruv.
Proud to be a Vegetarian.
http://www.vegetarianstarterkit.com/
http://www.vegkids.com/vegkids/index.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Andrei Alexandrescu (See Guest
|
Posted: Sun Apr 25, 2004 10:31 pm Post subject: Re: Using enum's as bit fields |
|
|
"Julio M. Merino Vidal" <jmmv (AT) menta (DOT) net> wrote
[snip]
| Quote: | I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
|
You can define operator| and operator& for your enumeration type to perform
the cast internally. The advantage is that you get typesafe combining and
extracting operations.
Andrei
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sun Apr 25, 2004 10:41 pm Post subject: Re: Using enum's as bit fields |
|
|
Julio M. Merino Vidal wrote:
| Quote: | enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
enum ENUMTEST e;
e = bit0 | bit2;
return 0;
Now, compile it as C and as C++:
[dawn tmp] $ cc -Wall test.c
[dawn tmp] $ c++ -Wall test.c
test.c: In function `int main()':
test.c:12: error: invalid conversion from `int' to `ENUMTEST'
I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
|
There are three things that come to my mind: one is bitfields, one is
std::bitfield<> and the other still uses enums.
The first is mostly
struct lowlevel
{
unsigned bit0:1;
unsigned bit1:1;
};
But you still can't use | on it yet. Skipping the second variant, we come
to the third (which also completes the first) and that is simply a matter
of adding an overloaded operator| like this:
enum test;
test operator|(test const& t1, test const& t2)
{
return static_cast<test>(
static_cast<int>(t1)|static_cast<int>(t2) );
}
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
llewelly Guest
|
Posted: Sun Apr 25, 2004 11:05 pm Post subject: Re: Using enum's as bit fields |
|
|
"Julio M. Merino Vidal" <jmmv (AT) menta (DOT) net> writes:
| Quote: | Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
[snip] |
enum test
{
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
test operator|(test lhs, test rhs)
{
return test(static_cast
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave Harris Guest
|
Posted: Sun Apr 25, 2004 11:14 pm Post subject: Re: Using enum's as bit fields |
|
|
[email]jmmv (AT) menta (DOT) net[/email] (Julio M. Merino Vidal) wrote (abridged):
| Quote: | I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
|
You can add operate|() and put the cast in there.
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
ENUMTEST operator|( ENUMTEST lhs, ENUMTEST rhs ) {
return ENUMTEST( int(lhs) | int(rhs) );
}
-- Dave Harris, Nottingham, UK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Apr 25, 2004 11:23 pm Post subject: Re: Using enum's as bit fields |
|
|
In message <pan.2004.04.25.04.04.03.256017 (AT) gmx (DOT) net>, Dhruv Matani
<dhruvbird (AT) gmx (DOT) net> writes
| Quote: | main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
bit0 | bit2 is NOT a member of the enum.
|
Yes but understanding why helps to provide a solution. The value of
(bit0 | bit2) most certainly is a legitimate value for ENUMTEST (the
Standard was carefully written so that would be true) but if no
operator| has been defined for ENUMTEST it uses the builtin operator|
for int which evaluates to an int.
For safety reasons C++ (unlike C) does not allow implicit conversions
from int to an enum type. The solution for C compatibility when you
really want is:
#ifdef __cplusplus
inline ENUMTEST operator|(ENUMTEST e1, ENUMTEST e2){
return ENUMTEST((int)e1 | (int)e2);
}
// add similar definitions for any other operators you want
// to use on ENUMTEST
#endif
Now a C++ compiler will see those explicit overloads and use them while
a C compiler will just use its own (type unsafe) alternative.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Sun Apr 25, 2004 11:24 pm Post subject: Re: Using enum's as bit fields |
|
|
Julio M. Merino Vidal <jmmv (AT) menta (DOT) net> wrote:
| Quote: | Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
int
main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
return 0;
}
Now, compile it as C and as C++:
[dawn tmp] $ cc -Wall test.c
[dawn tmp] $ c++ -Wall test.c
test.c: In function `int main()':
test.c:12: error: invalid conversion from `int' to `ENUMTEST'
I can use an explicit cast when setting e's value (to avoid the error),
but I don't like this approach. Is it there another way to do this same
thing in C++? Or should I use std::bitfiled instead?
Thanks!
Since C++ requires an explicit cast and C does not you could do this |
in a header, and it should produce the same results in C or C++.
typedef enum E_t
{
bit0=1,bit2=2,bit3=4
} E;
#ifdef __cplusplus
inline E operator | (E x,E y) {return static_cast
inline E operator & (E x,E y) {return static_cast<E>(x&y);}
// other bitwise operators if desired.
#endif
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dhruv Matani Guest
|
Posted: Mon Apr 26, 2004 8:24 am Post subject: Re: Using enum's as bit fields |
|
|
On Sun, 25 Apr 2004 19:23:52 -0400, Francis Glassborow wrote:
| Quote: | In message <pan.2004.04.25.04.04.03.256017 (AT) gmx (DOT) net>, Dhruv Matani
[email]dhruvbird (AT) gmx (DOT) net[/email]> writes
main(void)
{
enum ENUMTEST e;
e = bit0 | bit2;
bit0 | bit2 is NOT a member of the enum.
Yes but understanding why helps to provide a solution. The value of
(bit0 | bit2) most certainly is a legitimate value for ENUMTEST (the
Standard was carefully written so that would be true) but if no
operator| has been defined for ENUMTEST it uses the builtin operator|
for int which evaluates to an int.
|
Meaning that all values < bit3 (filled in filly by 1) are valid for the
enum?
So, all values < 111(2) => 7 are valid?
I did not know about this! Thanks ;-)
--
Regards,
-Dhruv.
Proud to be a Vegetarian.
http://www.vegetarianstarterkit.com/
http://www.vegkids.com/vegkids/index.html
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Apr 26, 2004 10:18 am Post subject: Re: Using enum's as bit fields |
|
|
In message <1gcrvxh.1uas4c31156ymuN%cbarron3 (AT) ix (DOT) netcom.com>, Carl Barron
<cbarron3 (AT) ix (DOT) netcom.com> writes
| Quote: | #ifdef __cplusplus
inline E operator | (E x,E y) {return static_cast<E>(x|y);}
|
Unfortunately that creates a recursive definition so you must also apply
a cast to x and y.
| Quote: | inline E operator & (E x,E y) {return static_cast<E>(x&y);}
|
Ditto.
| Quote: | // other bitwise operators if desired.
#endif
|
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Apr 26, 2004 2:36 pm Post subject: Re: Using enum's as bit fields |
|
|
In message <pan.2004.04.26.04.02.48.68958 (AT) gmx (DOT) net>, Dhruv Matani
<dhruvbird (AT) gmx (DOT) net> writes
| Quote: | Meaning that all values < bit3 (filled in filly by 1) are valid for the
enum?
So, all values < 111(2) => 7 are valid?
|
Yes the Standard makes it clear that all values that can be expressed by
the smallest bit-field that could represent all the enumerators are
valid values for the enum type.
| Quote: |
I did not know about this! Thanks
|
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Michael Jørgensen Guest
|
Posted: Thu Apr 29, 2004 10:35 pm Post subject: Re: Using enum's as bit fields |
|
|
"Julio M. Merino Vidal" <jmmv (AT) menta (DOT) net> wrote
| Quote: | Hi all,
in C, it's common practice to use an enumeration to define several
values as a bit field, and then use the enumeration type to define
function parameters or variables. Consider the following example:
enum ENUMTEST {
bit0 = 1 << 0,
bit1 = 1 << 1,
bit2 = 1 << 2
};
|
Just a word of caution:
I've been bitten hard with the fact that sizeof(ENUMTEST) is different in C
and C++.
I once had some similar enumerations defined in a common header file that
was #included from regular C files and from C++ files. Furthermore, this
enumeration was part of a structure that was passed between functions in the
two groups of source files.
Because the enumeration had different size, the layout of the structure was
different in the two groups of files. This led to hard-to-find bugs.
I realize this is specified quite clearly in the standard, but it was a very
unpleasant surprise to me. Furthermore, it was not trivial to solve, because
the C functions were legacy code, not changeable.
Since then I've learnt to be very careful when using enumerations,
particularly whenever there are any C files around.
-Michael.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Dennett Guest
|
Posted: Sun May 02, 2004 11:01 am Post subject: Re: Using enum's as bit fields |
|
|
Michael Jørgensen wrote:
| Quote: |
Just a word of caution:
I've been bitten hard with the fact that sizeof(ENUMTEST) is different in C
and C++.
I once had some similar enumerations defined in a common header file that
was #included from regular C files and from C++ files. Furthermore, this
enumeration was part of a structure that was passed between functions in the
two groups of source files.
Because the enumeration had different size, the layout of the structure was
different in the two groups of files. This led to hard-to-find bugs.
I realize this is specified quite clearly in the standard, but it was a very
unpleasant surprise to me. Furthermore, it was not trivial to solve, because
the C functions were legacy code, not changeable.
Since then I've learnt to be very careful when using enumerations,
particularly whenever there are any C files around.
|
Indeed, some C++ compilers have an option to force all enums
to be a particular size, which can be the most practical
solution when interoperating with C code which relies on this.
-- James
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|