Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type of a bitfield?

I can't find anywhere in the C standard where this is specified. For example, in

struct { signed int x:1; } foo;

is foo.x an lvalue of type int, or something else? It seems unnatural for it to be an lvalue of type int since you cannot store any value of type int in it, only 0 or -1, but I can't find any language that would assign it a different type. Of course, used in most expressions, it would get promoted to int anyway, but the actual type makes a difference in C11 with _Generic, and I can't find any language in the standard about how bitfields interact with _Generic either.

like image 236
R.. GitHub STOP HELPING ICE Avatar asked Oct 28 '12 00:10

R.. GitHub STOP HELPING ICE


People also ask

What is BitField structure?

A bit field is a data structure that consists of one or more adjacent bits which have been allocated for specific purposes, so that any single bit or group of bits within the structure can be set or inspected.

How does a BitField work?

In programming terminology, a bit field is a data structure that allows the programmer to allocate memory to structures and unions in bits in order to utilize computer memory in an efficient manner. Since structures and unions are user-defined data types in C, the user has an idea of how much memory will they occupy.

Can we reference a bit field?

Pointers and non-const references to bit-fields are not possible.

Can we have an array of bit field?

No, you can't. Bit field can only be used with integral type variables.


Video Answer


2 Answers

As Jonathan already cited, p5 clearly states what the type a bit-field has.

What you should have also in mind is that there is a special rule for bit-field arithmetic conversions in 6.3.1.1, basically stating that if an int can represent all values such a bit-field converts to an int in most expressions.

What the type would be in a _Generic should be the declared type (modulo the sign glitch), since it seems to be consensus that arithmetic conversions don't apply, there. So

_Generic((X), int: toto, unsigned: tutu)
_Generic(+(X), int: toto, unsigned: tutu)

could give you different results if X is an unsigned bit-field with a width that has all values fit into an int.

like image 76
Jens Gustedt Avatar answered Sep 18 '22 17:09

Jens Gustedt


Given that you included the signed qualifier, then the only values that can be stored in the 1-bit bit field are indeed -1 and 0. If you'd omitted the qualifier, it would be implementation defined whether the 'plain' int bit field was signed or unsigned. If you'd specified unsigned int, of course, the values would be 0 and +1.

The relevant sections of the standard are:

§6.7.2.1 Structure and union specifiers

¶4 The expression that specifies the width of a bit-field shall be an integer constant expression with a nonnegative value that does not exceed the width of an object of the type that would be specified were the colon and expression omitted.122) If the value is zero, the declaration shall have no declarator.

¶5 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. It is implementation-defined whether atomic types are permitted.

¶10 A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits.125) If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare equal to the value stored; a _Bool bit-field has the semantics of a _Bool.

122) While the number of bits in a _Bool object is at least CHAR_BIT, the width (number of sign and value bits) of a _Bool may be just 1 bit.

125) As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int, then it is implementation-defined whether the bit-field is signed or unsigned.

The footnote 125 points to:

§6.7.2 Type Specifiers

¶5 Each of the comma-separated multisets designates the same type, except that for bitfields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int.

like image 21
Jonathan Leffler Avatar answered Sep 19 '22 17:09

Jonathan Leffler