Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > enum as bitfields

Reply
Thread Tools

enum as bitfields

 
 
Quentin Pope
Guest
Posts: n/a
 
      09-29-2011
Hello,

Does the C standard say anything about using enum in a bit field? Like

enum {
apple,
orange

} fruit;

struct {
enum fruit f:16;

};

Gcc does not complain about this when -ansi or -pedantic is turned
OFF. XLC (claims to be an ANSI C compiler) on the IBM RS/6000 issued
a warning and treat it like an unsigned integer. K&R 2nd Ed says
nothing explicitly about this but it says that bit fields are
`implementation dependant' and `always unsigned'.

I think this is very useful and in our project we encourage people to use
enum instead of #define to create constants. Although not used in a lot
of places, the bit field somewhat defeats this purpose. Is there a
rationale why this is so? Is there any way to shut up the compiler?
I've checked the FAQ. No answers from there.

Thanks
QP
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      09-29-2011
On 09/29/2011 04:30 PM, Quentin Pope wrote:
> Hello,
>
> Does the C standard say anything about using enum in a bit field? Like
>
> enum {
> apple,
> orange
>
> } fruit;
>
> struct {
> enum fruit f:16;
>
> };
>
> Gcc does not complain about this when -ansi or -pedantic is turned
> OFF. XLC (claims to be an ANSI C compiler) on the IBM RS/6000 issued
> a warning and treat it like an unsigned integer.


6.7.2.1p4: "A bit-field shall have a type that is a qualified or
unqualified version of _Bool, signed int, unsigned int, or some other
implementation-defined type."

This means that an implementation can accept other types, in which case
no diagnostic is required, but that an implementation is not required to
accept any other types. Code that's intended to be portable should
therefore not use other types.

> ... K&R 2nd Ed says
> nothing explicitly about this but it says that bit fields are
> `implementation dependant' and `always unsigned'.


Many features of bit fields are implementation-dependent; but it's not
clear which of those features that comment might be about. A bit field
declared as 'signed int' is unambiguously signed. Are you sure that K&R2
claims that bit-fields are "always unsigned"?

6.7.2.1p4 seems to imply that an implementation is not required to
accept a bit field declared with plain 'int', something I had not
noticed before. However, if an implementation does accept it, then
6.7.2p5 applies: "for bit-fields, it is implementation-defined whether
the specifier int designates the same type as signed int or the same
type as unsigned int." From this I conclude that, even if an
implementation does allow use of plain 'int' for bit fields, no sane
programmer should ever take advantage of that fact.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-29-2011
Quentin Pope <> writes:
> Does the C standard say anything about using enum in a bit field? Like
>
> enum {
> apple,
> orange
>
> } fruit;
>
> struct {
> enum fruit f:16;
>
> };


Yes. C99 6.7.2.1p4:

A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed int, unsigned int, or some other
implementation-defined type.

This is a constraint, and "implementation-defined" means that the
ipmlementation must document any other types, so the compiler (in
conforming mode) must complain about an enum bit-field *unless*
the compiler's documentation specifically says that it's permitted.

More generally, using a bit field of a type other than the ones
listed in the standard makes your code non-portable. (Using bit
fields is likely to do that as well, if you're assuming that it
defines the layout precisely.)

[...]

> I think this is very useful and in our project we encourage people to use
> enum instead of #define to create constants. Although not used in a lot
> of places, the bit field somewhat defeats this purpose. Is there a
> rationale why this is so? Is there any way to shut up the compiler?
> I've checked the FAQ. No answers from there.


In the example you've shown us, making "f" a bit field doesn't make much
sense; it would be simpler to write just "enum fruit f;". Why do you
need f to be exactly 16 bits?

If your purpose is to define some constants, you can use enumerations
without necessarily using the enumeration type. For example:

enum { apple, orange };
struct basket { unsigned f:16; };
struct basket b;

b.f = apple;

Enumeration constants in C are not actually of the enumeration type;
they're always of type int.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-29-2011
Quentin Pope <> writes:

> Does the C standard say anything about using enum in a bit field? Like
>
> enum {
> apple,
> orange
>
> } fruit;


(you mean enum fruit {...}; not enum {...} fruit; I think)

> struct {
> enum fruit f:16;
>
> };


Yes, it does. There is a constraint:

A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed int, unsigned int, or some other
implementation-defined type.

which, if violated would make your program undefined and would require a
diagnostic. However, from the wording it would seem that an
implementation that documents the possibility of using an enum, may
accept this code without saying a word.

> Gcc does not complain about this when -ansi or -pedantic is turned
> OFF. XLC (claims to be an ANSI C compiler) on the IBM RS/6000 issued
> a warning and treat it like an unsigned integer. K&R 2nd Ed says
> nothing explicitly about this but it says that bit fields are
> `implementation dependant' and `always unsigned'.


You may be misreporting this. K&R2 sticks close to what was called ANSI
C, and in ANSI C, bit fields can be signed. My quote above is from the
newer 1999 C standard.

> I think this is very useful and in our project we encourage people to use
> enum instead of #define to create constants. Although not used in a lot
> of places, the bit field somewhat defeats this purpose. Is there a
> rationale why this is so? Is there any way to shut up the compiler?


There might be. You name two compilers and the one that complains is
one I don't know. gcc also has something to say if put into conforming
mode, though what it does is simply to remind you that this is an
extension:

$ gcc -std=c99 -pedantic -c x.c
x.c:8:8: warning: type of bit-field ‘f’ is a GCC extension

I don't think this is one you can turn off. My reading of the standard
is that gcc could silently accept this code in conforming mode, but it
is not obliged to do so. A compiler is permitted to issue pretty much
any diagnostics it likes, as far as the standard is concerned.

--
Ben.
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      09-29-2011
Quentin Pope <> writes:

> Does the C standard say anything about using enum in a bit field?


It doesn't say that it's allowed, except as an implementation
extension:

4 A bit-field shall have a type that is a qualified or
unqualified version of _Bool, signed int, unsigned int, or
some other implementation-defined type.

--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      09-30-2011
James Kuyper <> writes:
[...]
> 6.7.2.1p4: "A bit-field shall have a type that is a qualified or
> unqualified version of _Bool, signed int, unsigned int, or some other
> implementation-defined type."

[...]

> 6.7.2.1p4 seems to imply that an implementation is not required to
> accept a bit field declared with plain 'int', something I had not
> noticed before.


I don't think so. The same reasoning would imply that you can't declare
a bit-field as "unsigned", "int unsigned", or "signed". 6.7.2p2
indicates that "int", "signed", and "signed int" are all names for the
same type.

I'm 99% sure that the intent is implementations are required to support
that plain "int" bit-fields.

> However, if an implementation does accept it, then
> 6.7.2p5 applies: "for bit-fields, it is implementation-defined whether
> the specifier int designates the same type as signed int or the same
> type as unsigned int." From this I conclude that, even if an
> implementation does allow use of plain 'int' for bit fields, no sane
> programmer should ever take advantage of that fact.


--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Harald van Dijk
Guest
Posts: n/a
 
      09-30-2011
On Sep 30, 6:11*am, Keith Thompson <ks...@mib.org> wrote:
> James Kuyper <jameskuy...@verizon.net> writes:
>
> [...]> 6.7.2.1p4: "A bit-field shall have a type that is a qualified or
> > unqualified version of _Bool, signed int, unsigned int, or some other
> > implementation-defined type."

>
> [...]
>
> > 6.7.2.1p4 seems to imply that an implementation is not required to
> > accept a bit field declared with plain 'int', something I had not
> > noticed before.

>
> I don't think so. *The same reasoning would imply that you can't declare
> a bit-field as "unsigned", "int unsigned", or "signed". *6.7.2p2
> indicates that "int", "signed", and "signed int" are all names for the
> same type.


Bit-fields are a special case where int and signed int are not
necessarily synonymous: plain int may be treated as either signed or
unsigned. However, whichever it is, it is not like char, where plain
char is a distinct type from the signed and unsigned varieties.
6.7.2p5 makes it clear that plain int is either signed int, or
unsigned int.

> I'm 99% sure that the intent is implementations are required to support
> that plain "int" bit-fields.


Sure.
 
Reply With Quote
 
Quentin Pope
Guest
Posts: n/a
 
      10-01-2011
On Thu, 29 Sep 2011 22:11:18 +0100, Ben Bacarisse wrote:

> Quentin Pope <> writes:
>
>> Does the C standard say anything about using enum in a bit field? Like
>>
>> enum {
>> apple,
>> orange
>>
>> } fruit;

>
> (you mean enum fruit {...}; not enum {...} fruit; I think)
>
>> struct {
>> enum fruit f:16;
>>
>> };

>
> Yes, it does. There is a constraint:
>
> A bit-field shall have a type that is a qualified or unqualified
> version of _Bool, signed int, unsigned int, or some other
> implementation-defined type.
>
> which, if violated would make your program undefined and would require a
> diagnostic. However, from the wording it would seem that an
> implementation that documents the possibility of using an enum, may
> accept this code without saying a word.


So in effect, it may or may not be a constraint violation, depending on
whether the underlying type of the enum is int, unsigned int or something
else?
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      10-01-2011
On 10/01/2011 04:59 AM, Quentin Pope wrote:
> On Thu, 29 Sep 2011 22:11:18 +0100, Ben Bacarisse wrote:
>
>> Quentin Pope <> writes:
>>
>>> Does the C standard say anything about using enum in a bit field? Like
>>>
>>> enum {
>>> apple,
>>> orange
>>>
>>> } fruit;

>>
>> (you mean enum fruit {...}; not enum {...} fruit; I think)
>>
>>> struct {
>>> enum fruit f:16;
>>>
>>> };

>>
>> Yes, it does. There is a constraint:
>>
>> A bit-field shall have a type that is a qualified or unqualified
>> version of _Bool, signed int, unsigned int, or some other
>> implementation-defined type.
>>
>> which, if violated would make your program undefined and would require a
>> diagnostic. However, from the wording it would seem that an
>> implementation that documents the possibility of using an enum, may
>> accept this code without saying a word.

>
> So in effect, it may or may not be a constraint violation, depending on
> whether the underlying type of the enum is int, unsigned int or something
> else?


No - the underlying type of the enum is irrelevant. What is relevant is
the implementation's documentation: any additional types that the
documentation says are acceptable may be used. Since "A bit-field is
interpreted as a signed or unsigned integer type" (6.7.2.1p9), it
wouldn't make much sense for an implementation to accept non-integral
types. However, as far as the constraint listed above is concerned, if
an implementation were to document that it accepts 'double' as a type
for a bit-field, then even "double f:16" would not be a violation of the
constraint listed above.

Of course, portable code should only use the types that are guaranteed
to be allowed.
--
James Kuyper
 
Reply With Quote
 
Quentin Pope
Guest
Posts: n/a
 
      10-01-2011
On Sat, 01 Oct 2011 06:37:23 -0400, James Kuyper wrote:

> On 10/01/2011 04:59 AM, Quentin Pope wrote:
>> On Thu, 29 Sep 2011 22:11:18 +0100, Ben Bacarisse wrote:
>>
>>> Quentin Pope <> writes:
>>>
>>>> Does the C standard say anything about using enum in a bit field?
>>>> Like
>>>>
>>>> enum {
>>>> apple,
>>>> orange
>>>>
>>>> } fruit;
>>>
>>> (you mean enum fruit {...}; not enum {...} fruit; I think)
>>>
>>>> struct {
>>>> enum fruit f:16;
>>>>
>>>> };
>>>
>>> Yes, it does. There is a constraint:
>>>
>>> A bit-field shall have a type that is a qualified or unqualified
>>> version of _Bool, signed int, unsigned int, or some other
>>> implementation-defined type.
>>>
>>> which, if violated would make your program undefined and would require
>>> a diagnostic. However, from the wording it would seem that an
>>> implementation that documents the possibility of using an enum, may
>>> accept this code without saying a word.

>>
>> So in effect, it may or may not be a constraint violation, depending on
>> whether the underlying type of the enum is int, unsigned int or
>> something else?

>
> No - the underlying type of the enum is irrelevant. What is relevant is
> the implementation's documentation: any additional types that the
> documentation says are acceptable may be used. Since "A bit-field is
> interpreted as a signed or unsigned integer type" (6.7.2.1p9), it
> wouldn't make much sense for an implementation to accept non-integral
> types. However, as far as the constraint listed above is concerned, if
> an implementation were to document that it accepts 'double' as a type
> for a bit-field, then even "double f:16" would not be a violation of the
> constraint listed above.
>
> Of course, portable code should only use the types that are guaranteed
> to be allowed.


James

I think you may have misunderstood what I was saying.

My point was that if the enum type is an alias for int, then that is one
of the allowed types for a bitfield with no need for any implementation
documentation.

So although the code won't be portable to every implementation, it will
still be portable (no constraint violation) for all implementations where
enums have type int.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ENUM server for private ENUM kael UK VOIP 2 02-25-2007 11:54 AM
enum: display elements of an enum specified at runtime Jerminia Java 3 10-07-2005 10:08 PM
enum within an enum - Java 6 06-13-2005 12:51 AM
Including an enum within another enum, possible? mrhicks C Programming 2 06-10-2004 03:00 AM
How to enum an enum? Ernst Murnleitner C++ 5 11-13-2003 11:06 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57