Why and where does C standard allow this code compile? where is it useful?
struct foo { int : 12; }; Why and where does C standard allow this code compile? where is it useful?
struct foo { int : 12; }; That would be in §6.7.2.1 Structure and union specifiers
12) A bit-field declaration with no declarator, but only a colon and a width, indicates an unnamed bit-field.126
The footnote explains why such things exist:
126 An unnamed bit-field structure member is useful for padding to conform to externally imposed layouts.
That being said, the same part of the standard (paragraph 8) also states:
If the struct-declaration-list does not contain any named members, either directly or via an anonymous structure or anonymous union, the behavior is undefined.
But some compilers (GCC and clang at least) allow this anyway, as an extension.
The use is a bit limited if that's the only bitfield in the struct, but not impossible to use as ouah illustrates.
The standard continues on with another "oddity":
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 bitfield, if any, was placed.
This program invokes undefined behavior.
C says:
(C99, 6.7.2.1p7) "[...] If the struct-declaration-list contains no named members, the behavior is undefined."
Now some compilers accept it as an extension. How can this be useful?
For example for Linux kernel famous BUILD_BUG_ON_ZERO macro:
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) To see what does this macro, you can look here.
BUILD_BUG_ON_ZERO macro uses a struct type which contains no names, it doesn't look like the trick is relying on this in any way (other than that not using names is more hygienic than using names). They key is that a failed expression produces a negative value for the bitfield size, which is diagnosed.gcc stops translation with an named bit-field of width of 0.BUILD_BUG_ON_ZERO has to bug if e is non-zero and has to yield 0 if e is 0. See for example Linux ARRAY_SIZE macro implementation which assumes this and uses BUILD_BUG_ON_ZERO as an identity element when e is 0. By adding a dummy named member (which cannot have a 0 width as we saw above), you can no longer fill the constraint of having a BUILD_BUG_ON_ZERO yielding 0 when e is 0.#define BUILD_BUG_ON_ZERO(e) (<standard-conforming hack here>, 0) or #define BUILD_BUG_ON_ZERO(e) ((<standard-conforming-hack>) * 0) etc. It doesn't matter what the hack returns; all we care is whether it blows up at compile time or not.Well, according to the language specification, if your program contains a struct type without named members, the behavior is undefined. (To the question of why it is not officially recognized as a constraint violation I have no immediate answer.) It is stated in 6.7.2.1/7
The struct-declaration-list is a sequence of declarations for the members of the structure or union. If the struct-declaration-list contains no named members, the behavior is undefined.
Other than that such declaration is not really "useful" since the only thing it produces is undefined behavior.