enums and bitfileds and signs

J

Jason Kraftcheck

If I have a struct defined as follows:

enum ABCD { A = 0, B = 1, C = 2, D = 3 };
struct Foo { ABCD val : 2; }

and I do:

Foo f;
f.val = C;
ABCD v = f.val;

With g++, v will have the value 'C'. With Microsoft's compiler it will
have a value of -2.

Which of these is the correct behavior? Or is using signed and/or enum
values in bit fields not well defined?
 
V

Victor Bazarov

Jason said:
If I have a struct defined as follows:

enum ABCD { A = 0, B = 1, C = 2, D = 3 };
struct Foo { ABCD val : 2; }

and I do:

Foo f;
f.val = C;
ABCD v = f.val;

With g++, v will have the value 'C'. With Microsoft's compiler it
will have a value of -2.

Which of these is the correct behavior? Or is using signed and/or
enum values in bit fields not well defined?

I don't belive the signedness is specified for enum-based bit-fields.
The requirement is that the size of the bit-field should allow storing
of _all_ values of the enum. If 'ABCD' has 'int' for its underlying
type, and since 'int' is signed, then 2 bits is not enough for 'val'
member, it has to have 3 (one for the sign bit, which should stay
unused, however). That's how I read it, anyway.

V
 
J

James Kanze

I don't belive the signedness is specified for enum-based
bit-fields. The requirement is that the size of the bit-field
should allow storing of _all_ values of the enum. If 'ABCD'
has 'int' for its underlying type, and since 'int' is signed,
then 2 bits is not enough for 'val' member, it has to have 3
(one for the sign bit, which should stay unused, however).
That's how I read it, anyway.

What about §7.2/7:

For an enumeration where emin is the smallest enumerator
and emax is the largest, the values of the enumeration
are the values in the range bmin to bmax, defined as
follows: Let K be 1 for a two's complement
representation and 0 for a one's complement or
sign-magnitude representation. bmax is the smallest
value greater than or equal to max(|emin|-K, |emax|) and
equal to 2M -1, where M is a non-negative integer. bmin
is zero if emin is non-negative and -(bmax+K) otherwise.
The size of the smallest bit-field large enough to hold
all the values of the enumeration type is max(M,1) if
bmin is zero and M+1 otherwise. It is possible to define
an enumeration that has values not defined by any of its
enumerators.

By my calculations, given his values above, M is 2, so the
size of the smallest bit-field large enough to hold all the
values of the enumeration type is 2. The values of the
enumeration type are A, B, C and D---if he assigns one of
these values to a bit-field of at least 2 bits, he is
guaranteed to get it back when he rereads it.

Note that this is a subtle difference between C and C++. C
doesn't make any real guarantees with regards to enums in
bit fields, and Microsoft's implementation would presumably
be legal in C (although from a quality of implementation
point of view, I think it should be considered a bug even in
C).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

enums and signed/unsigned 4
Linux: using "clone3" and "waitid" 0
Classes for enums 5
Blue J Ciphertext Program 2
enums clash 9
Enums: Properties vs. Methods 33
enums and bitfields 2
Fixing "typos" in enums... 18

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top