[Dwarf-Discuss] Unnamed zero sized bit-fields (Re: Corner-cases with bitfields)

Michael Eager eager at eagercon.com
Tue May 10 09:29:44 PDT 2022

On 5/10/22 04:10, Pedro Alves via Dwarf-Discuss wrote:
> On 2022-05-06 18:11, Lancelot SIX via Dwarf-Discuss wrote:
>> 2 - Unnamed zero sized bitfield
>> Another case we met is related to unnamed fields with a size of 0 bits.
>> Such field is defined in the c++ standard as (in 9.6 Bit-Fields):
>>   > 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
>> If we now consider an extended version of our previous example:
>>       struct Foo
>>       {
>>         char a : 8;
>>         char : 0;
>>         char b : 8,
>>       };
>> Neither GCC nor Clang give any information about the unnamed bitfield.
>> As for the previous case, the presence of such field impacts how
>> arguments are passed during function calls on our target, leaving the
>> debugger unable to properly decide how to handle such cases.
>> As for the previous case, both compilers can properly describe Foo's
>> memory layout using DW_AT_bit_offset.
>> It seems that such 0-sized field also has impact on ABI on other targets
>> such as armv7hl and aarch64 as discussed in [2].  Should the DWARF
>> specification give some guidance on how to handle such situation?
>> All thoughts on those cases are welcome.
> In DWARF 5, we have:
> "5.7.6
>   Data Member Entries
> A data member (as opposed to a member function) is represented by a
> debugging information entry with the tag DW_TAG_member. The member
> entry for a named member has a DW_AT_name attribute whose value is a
> null-terminated string containing the member name. If the member entry
> describes an anonymous union, the name attribute is omitted or the value of the
> attribute consists of a single zero byte."
> I didn't find anything that would prevent a producer from emitting an
> unnamed bit-field member.  Ignoring the 0-size special case for the moment,
> neither GCC nor Clang emit the unnamed bit-field in this case either:
>      struct Foo
>      {
>        char a : 8;
>        char : 8;
>        char b : 8;
>      };
> I suppose you could call it QoI to emit an unnamed field for this unnamed bit-field,
> in the same vein of what I mentioned earlier about making it possible for the debugger to
> reconstruct the original type (a debugger could infer the size of the unnamed bit-field
> from the gap, but not its declared type).  I didn't find wording in the spec that
> would prevent it.

Nothing in DWARF would seem to prohibit generating a unnamed field, nor
would anything require it.  It's QoI; with it a debugger can print an
field without a name, without you cannot.  (It's possible that a 
debugger might not expect a zero-size field, but that, too, is QoI.)

>  From that angle, unnamed zero-sized bit-fields could also be emitted, ISTM that it's
> technically possible to describe it with current DWARF, though, consumer-implementation-wise,
> a consumer may need to be able to distinguish "no DW_AT_bit_size present" vs
> "DW_AT_bit_size present and value is 0".  Anyone see an issue with making that distinction
> DWARF-spec wise?  Could that result in ambiguities somewhere?  I don't think that GDB makes
> such a distinction currently, I think internally "bit size == 0" means not a bit field,
> but that would be changed, of course, it's implementation detail.

A proposal for DWARF to require DW_AT_bit_size for all bit fields would
address this.

> For some reason (maybe because of the weird "single zero byte" special case?), the
> wording above from 5.7.6 describes what to do with anonymous unions, kind of giving
> the impression that it could also specify what is expected with other unnamed fields
> such as unnamed bit-fields.

That line might be tweaked to apply to all unnamed entities.

> OTOH, we have "D.2.8 C/C++ Bit-Field Examples", where the spec says "Bit fields in C and C++
> typically require the use of the DW_AT_data_bit_offset and DW_AT_bit_size attributes.".
> It then goes on to give examples of big- and little-endian machines.  Maybe this chapter would
> be the spot where the spec would give the example of what to do with unnamed bit-fields
> of 0 size, as _it is_ a special case described in the C++ language spec, i.e., has meaning
> at the language level that is lost otherwise, and the D.2.8 chapter in the DWARF spec is
> specifically about C/C++.

The Appendices are not normative parts of the standard.  They only offer
suggestions on how to represent various situations.  Changes in how
unnamed bit fields should be described would be in the body of the 
standard.  (And the example could be extended.)

> Or this is yet another case that people would prefer to leave things as is DWARF-spec-wise
> and we should go file bug reports with GCC and Clang?

Submit an issue to DWARF to have the standard clarified/enhanced and
file a bug report with GCC & Clang.

Michael Eager

More information about the Dwarf-Discuss mailing list