143
struct _USBCHECK_FLAGS
    {
        unsigned char   DEVICE_DEFAULT_STATE       : 1;
        unsigned char   DEVICE_ADDRESS_STATE       : 1;
        unsigned char   DEVICE_CONFIGURATION_STATE : 1;
        unsigned char   DEVICE_INTERFACE_STATE     : 1;
        unsigned char   FOUR_RESERVED_BITS         : 8;
        unsigned char   RESET_BITS                 : 8;
    } State_bits;

What does :1 and :8 mean?

Pubby
  • 51,882
  • 13
  • 139
  • 180
Mohamed Maged
  • 1,443
  • 2
  • 10
  • 5

2 Answers2

106

Those are bit fields. Basically, the number after the colon describes how many bits that field uses. Here is a quote from MSDN describing bit fields:

The constant-expression specifies the width of the field in bits. The type-specifier for the declarator must be unsigned int, signed int, or int, and the constant-expression must be a nonnegative integer value. If the value is zero, the declaration has no declarator. Arrays of bit fields, pointers to bit fields, and functions returning bit fields are not allowed. The optional declarator names the bit field. Bit fields can only be declared as part of a structure. The address-of operator (&) cannot be applied to bit-field components.

Unnamed bit fields cannot be referenced, and their contents at run time are unpredictable. They can be used as "dummy" fields, for alignment purposes. An unnamed bit field whose width is specified as 0 guarantees that storage for the member following it in the struct-declaration-list begins on an int boundary.

This example defines a two-dimensional array of structures named screen.

struct 
{
    unsigned short icon : 8;
    unsigned short color : 4;
    unsigned short underline : 1;
    unsigned short blink : 1;
} screen[25][80];

Edit: another important bit from the MSDN link:

Bit fields have the same semantics as the integer type. This means a bit field is used in expressions in exactly the same way as a variable of the same base type would be used, regardless of how many bits are in the bit field.

A quick sample illustrates this nicely. Interestingly, with mixed types the compiler seems to default to sizeof (int).

  struct
  {
    int a : 4;
    int b : 13;
    int c : 1;
  } test1;

  struct
  {
    short a : 4;
    short b : 3;
  } test2;

  struct
  {
    char a : 4;
    char b : 3;
  } test3;

  struct
  {
    char a : 4;
    short b : 3;
  } test4;

  printf("test1: %d\ntest2: %d\ntest3: %d\ntest4: %d\n", sizeof(test1), sizeof(test2), sizeof(test3), sizeof(test4));

test1: 4

test2: 2

test3: 1

test4: 4

Community
  • 1
  • 1
JoeFish
  • 3,009
  • 1
  • 18
  • 23
  • I still don't get it. Does that mean C++ automatically merges your "variables" into size of an int, so that all bits are used? Can you cast bit field structiores to numbers to obtain the typical "*int with flags*". – Tomáš Zato Nov 30 '15 at 09:04
  • @TomášZato I have updated my answer with more information for you – JoeFish Nov 30 '15 at 18:13
  • 1
    @JoeFish Can you elaborate the merging details of the `test1-4`? – smwikipedia Jul 16 '16 at 07:55
  • 1
    I don't understand why `test4: 4` and I got `test4: 2` on Darwin Kernel Version 17.0.0 x86_64 – Aleksey Oct 05 '17 at 10:14
  • @Aleksey Remember that almost everything about bit fields is implementation dependent. it depends on hardware architecture and structure member alignment model. – Kevin Chou Jul 19 '20 at 05:11
  • 2
    @smwikipedia provoid a simple and understandable principles here: if both fields of `int` type can fit into a single int (i.e. 32 bits in the example above), the compiler allocates only a single int's worth of memory (test_1, short type for test_2, char type for test3). Ignored in the above example, if a single int can't hold the bitfields anymore, we add a second one. ref to this [example](https://stackoverflow.com/a/49722670/8691463) for more elaborate explanation. – Kevin Chou Jul 19 '20 at 05:16
25

I also ran into the colon notation but in my context bit fields didn't make sense. So I did some digging. This notation is also used for assigning values - in my specific situation pointers to functions.

Source: http://www.tldp.org/LDP/lkmpg/2.4/html/c577.htm

Below is a sample and an excerpt to explain.

"There is a gcc extension that makes assigning to this structure more convenient. You'll see it in modern drivers, and may catch you by surprise. This is what the new way of assigning to the structure looks like:"

struct file_operations fops = {
   read: device_read,
   write: device_write,
   open: device_open,
   release: device_release
};

The C99 (old, compatible) way looks like:

struct file_operations fops = {
   .read = device_read,
   .write = device_write,
   .open = device_open,
   .release = device_release
};
ykuksenko
  • 399
  • 3
  • 4
  • I have also seen this! I always thought the gcc extension was `.x = y` and the standard adopted it, until later I saw the `x: y` notation. The standard one looks better, I believe. – Shahbaz Oct 30 '13 at 18:36
  • 10
    Firstly, this is not assignment, it is *initialization*. Secondly, the feature you describe (*designated initializers*) has absolutely nothing to do with what the question is about (*bit fields*). Just because the obsolete GCC extension used `:` in the syntax does not mean it is in any way related to `:` in the question. – AnT stands with Russia Oct 30 '13 at 18:37
  • 23
    AnT, someone searching for "C struct initialization colon" may find this answer, and it's exactly what I was looking for. Thanks, user27346! – ChrisPhoenix Nov 27 '15 at 21:02
  • 1
    Later readers need to be aware of :colon `:` appear in c structure declaration(the question belongs to) and initialization at definition(the answer belongs to) are not the same thing. – Kevin Chou Jul 19 '20 at 05:27