16

I saw the following example in the C standard draft (n1570):

$3.14 paragraph 4 : A structure declared as:

struct 
{
        char a;
        int b:5, c:11, :0, d:8;
        struct 
        { 
            int ee:8; 
        } e;
}

So, What does :0 mean?

I know what a bit-field is, but :0 is without a name, which I do not understand.

What is the purpose of :0 without any identifier?

msc
  • 33,420
  • 29
  • 119
  • 214
  • See: [What is zero-width bit field](https://stackoverflow.com/q/13802728/1275169) and [Practical Use of Zero-Length Bitfields](https://stackoverflow.com/q/4297095/1275169). – P.P Aug 28 '17 at 10:35
  • 1
    Sidenote: If placement of bit within bit-field is important, you probably shouldn't be using bit-fields in the first place. – user694733 Aug 28 '17 at 10:47
  • 3
    I'm not very sure....is the marked dupe appropriate? It does not highlight this particular use, in the answers. – Sourav Ghosh Aug 28 '17 at 10:54
  • 3
    I've taken the liberty to re-open as the marked dupe is potentially _misleading_. If anyone has any other dupe, please do the honor. – Sourav Ghosh Aug 28 '17 at 11:28
  • 1
    @haccks sir, I myself reopened this question as it was earlier marked as dupe to the same question. Do you disagree with my view? – Sourav Ghosh Aug 28 '17 at 15:25
  • @SouravGhosh; I think second highly voted answer there answers the question. – haccks Aug 28 '17 at 15:28
  • 1
    @haccks OK, that is correct but I think this question had a different aspect, with the specific quote. In my view, they are not dupe, but complementary to each other, no offesnse sir. – Sourav Ghosh Aug 28 '17 at 15:30
  • 1
    @SouravGhosh; Question is: *What does :0 mean? What is the purpose of `:0` without any identifier?* The quote in the answer says: *"As a special case, an unnamed bit-field with a width of zero specifies alignment of the next bit-field at an allocation unit boundary."* followed by an example. Don't you think this answers the question asked here? AFAIS, your answer explained it further and added some more valuable information on the subject. – haccks Aug 28 '17 at 15:39
  • @haccks Right sir, I'm not contradicting you, rather saying about the last sentence you mentioned (_shy_), that's all. – Sourav Ghosh Aug 28 '17 at 15:41

3 Answers3

13

As the document you linked explains right before:

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration

It is a way to tell the compiler that b and c can/will be in the same memory location whereas d must be separate from them and can be modified concurrently to b/c

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • 1
    Given how implementation-dependent bit-fields are, I'd say there's no real point. If you require a specific bit layout, IMO it's much better to just mask out the bits yourself. – Andrew Henle Aug 28 '17 at 10:46
  • @AndrewHenle - no real point except for multithreaded access – Alex C Aug 28 '17 at 12:50
10

First of all, let's see chapter §6.7.2.1, Structure and union specifiers, P11. It says,

An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. [...]

But, in case, we explicitly want two consecutive bit-field members, which "might be" packed into a single memory location to reside on separate memory location (i.e., addressable storage unit ), the above is the way to force it.

The next paragraph, P12, mentions,

A bit-field declaration with no declarator, but only a colon and a width, indicates an unnamed bit-field.126) As a special case, a bit-field structure member with a width of 0 indicates that no further bit-field is to be packed into the unit in which the previous bit-field, if any, was placed.

following your example, this makes sure that the two bit-field members surrounding the :0 will be residing in separate memory location (not inside a single addressable storage unit, even if sufficient memory remains to pack them into one). This has the similar effect of having a non-bit-field member in between two bit-fields, to force the separation of the memory location.

Quoting C11, chapter §3.14, NOTE 2 (emphasis mine)

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration.

Also, regarding the usage ("why it is needed" part)

[...] The bit-fields b and c cannot be concurrently modified, but b and a, for example, can be.


Addendum:

Regarding the concurrency part, from NOTE 1

Two threads of execution can update and access separate memory locations without interfering with each other.

and, from chapter §5.1.2.4/P1,

Under a hosted implementation, a program can have more than one thread of execution (or thread) running concurrently. [...]

So, this is a theoretically viable option, as per the standard.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • *The bit-fields `b` and `c` cannot be concurrently modified, but `b` and `a`, for example, can be.* Where does that come from? The C language itself has no concept of "concurrency", and bit-fields are highly implementation-dependent. – Andrew Henle Aug 28 '17 at 10:50
  • @AndrewHenle That is a standard quote. I thought I was clear enough to mark the chapters. :) – Sourav Ghosh Aug 28 '17 at 10:51
  • I did a search of the C standard copy at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf and it didn't return the result. Weird. Interesting comment about threading in the standard there. – Andrew Henle Aug 28 '17 at 10:55
  • @AndrewHenle I see it there (even via your link).... Chapter §3.14, NOTE 4. You mind a re-check? – Sourav Ghosh Aug 28 '17 at 10:56
  • I found it. Perhaps the bolded text in the PDF is interfering with the search in Firefox's PDF viewer? Loading the standard into Acrobat Reader, and the text search finds the quote without any problems. – Andrew Henle Aug 28 '17 at 10:59
  • @AndrewHenle can't say sir, i'm on chrome. – Sourav Ghosh Aug 28 '17 at 11:00
  • @SouravGhosh: the most interesting part of 3.14 is Note 1, which hints that the purpose of the definition of _memory location_ is concurrency (races are defined in term of memory locations §5.1.2.4 ¶4, that paragraph would make a nice addition to this answer). – ninjalj Aug 28 '17 at 11:57
  • @ninjalj I thought that is already understood, but you are right, there's not harm being verbose. I'll add that, thank you. – Sourav Ghosh Aug 28 '17 at 12:11
3

It's a way of ensuring that bit-fileds, that might otherwise be combined into a single memory location, are not.

For example, let's say you have an 8-bit character but you wanted to ensure your two 3-bit fields were at separate locations (and thus could be modified concurrently). To achieve that, you could use:

struct xyzzy {
    int first  : 3,
               : 0,
    int second : 3;
};

and you wouldn't have to worry about filling out the space manually, such as with junk : 5.

For the language lawyers, C11 3.14 memory location /3 states (my emphasis):

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953