[PATCH v4] ungetc: Guarantee single char pushback

Siddhesh Poyarekar siddhesh@sourceware.org
Thu Dec 12 12:23:00 GMT 2024


On 2024-12-12 07:16, Maciej W. Rozycki wrote:
> On Wed, 11 Dec 2024, Siddhesh Poyarekar wrote:
> 
>>>> -  int _flags2;
>>>> +  int _flags2:24;
>>>> +  char _short_backupbuf[1];
>>>
>>> This doesn't create a 3-byte flags2, if that's what you're trying.
>>> The underlying storage will still be int-sized, now with 8 unallocated bits.
>>
>> gcc and clang both appear to pack in the struct just fine, which effectively
>> gives flags2 3-bytes storage and _short_backupbuf right next to it.  Maybe
>> I've misunderstood the issue you're trying to point out, could you please
>> elaborate?
> 
>   Indeed a bit-field does get packed with an eligible adjacent non-bitfield
> member of the structure, although ISO C defers storage unit allocation to
> the implementation and therefore I do believe it is down to the individual
> platform-specific ABI.
> 
>   Then e.g. the o32 MIPS ABI has this clause[1]:
> 
> "* Bit-fields can share a storage unit with other struct/union members,
>     including members that are not bit-fields.  Of course, struct members
>     occupy different parts of the storage unit."

That sounds like it's saying that distinct members cannot share the 
smallest addressable unit, i.e. a byte, which is fine.

> and the updated structure is laid out accordingly:
> 
> struct _IO_FILE {
> 	int                        _flags;               /*     0     4 */
> 	char *                     _IO_read_ptr;         /*     4     4 */
> 	char *                     _IO_read_end;         /*     8     4 */
> 	char *                     _IO_read_base;        /*    12     4 */
> 	char *                     _IO_write_base;       /*    16     4 */
> 	char *                     _IO_write_ptr;        /*    20     4 */
> 	char *                     _IO_write_end;        /*    24     4 */
> 	char *                     _IO_buf_base;         /*    28     4 */
> 	char *                     _IO_buf_end;          /*    32     4 */
> 	char *                     _IO_save_base;        /*    36     4 */
> 	char *                     _IO_backup_base;      /*    40     4 */
> 	char *                     _IO_save_end;         /*    44     4 */
> 	struct _IO_marker *        _markers;             /*    48     4 */
> 	struct _IO_FILE *          _chain;               /*    52     4 */
> 	int                        _fileno;              /*    56     4 */
> 
> 	/* XXX 3 bytes hole, try to pack */
> 	/* Bitfield combined with previous fields */
> 
> 	static int                        _flags2        /*     0: 0  0 */

Is the "static" a typo that may have confused the tool?

Sid


More information about the Libc-alpha mailing list