Path: csiph.com!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Regarding assignment to struct Date: Sun, 04 May 2025 18:42:34 -0700 Organization: None to speak of Lines: 121 Message-ID: <87y0vbomt1.fsf@nosuchdomain.example.com> References: <87ikmhp5x3.fsf@nosuchdomain.example.com> <87bjs8p1qd.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Mon, 05 May 2025 03:42:38 +0200 (CEST) Injection-Info: dont-email.me; posting-host="ce0368853eba606cbaed4ff885db219e"; logging-data="3586130"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/OMvDCD8kjM9aFb4oguY6Y" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:yuVtdn0WUiVD1iynXDWPROojsks= sha1:6tCBmfYV59cwmLJYXZnE46LlUm0= Xref: csiph.com comp.lang.c:393154 scott@slp53.sl.home (Scott Lurndal) writes: > Keith Thompson writes: >>James Kuyper writes: >>> On 5/3/25 20:37, Keith Thompson wrote: >>>> Lawrence D'Oliveiro writes: >>>>> On Sat, 3 May 2025 01:14:46 -0700, Andrey Tarasevich wrote: >>>>>> Virtually every C project relies on assignment of structures. >>>>>> Passing-returning structs by value might be more rare (although >>>>>> perfectly valid and often appropriate too), but assignment... >>>>>> assignment is used by everyone everywhere without even giving it a >>>>>> second thought. >>>>> >>>>> There is a caveat, to do with alignment padding: will this always have a >>>>> defined value? >>>> >>>> I don't believe so. In a quick look, I don't see anything in >>>> the standard that explicitly addresses this, but I believe that a >>>> conforming implementation could implement structure assignment by >>>> copying the individual members, leaving any padding in the target >>>> undefined. >>> >>> "When a value is stored in an object of structure or union type, >>> including in a member object, the bytes of the object representation >>> that correspond to any padding bytes take unspecified values.56)" >>> (6.2.6.1p6). >>> >>> That refers to footnote 56, which says "Thus, for example, structure >>> assignment need not copy any padding bits." >> >>Yes, that's what I missed. >> >>It's interesting that the footnote refers to padding *bits* rather than >>padding *bytes*. I presume this was unintentional. > > Padding bits: > > struct A { > uint64_t tlen : 16, > : 20, > pkind : 6, > fsz : 6, > gsz : 14, > g : 1, > ptp : 1; > } s; > > There are 20 padding bits in this declaration. Perhaps that's > what they're referring to? I don't believe so, at least not entirely. For one thing the terms "padding bits" is used only to refer to bits in the representation of an integer object that do not contribute to the object's value, and "padding bytes" is used only to refer to unused bytes within a struct or union. (Neither term is in italics, so there is no formal definition for either, but the standard's usage is consistent.) The standard does use the word "padding" in reference to unnamed bit-fields, but not "padding bits". (Pointer and floating-point objects may have bits that don't contribute to their values, but the standard doesn't say enough about their representations for the concept of padding bits to be necessary.) Furthermore the sentence to which the footnote is attached says: When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values. and the footnote says: Thus, for example, structure assignment need not copy any padding bits. The switch from "padding bytes" to "padding bits" seems odd. Of course bytes are made of bits, so it's not unreasonable to say that padding bytes are made of padding bits, particularly since neither term has a formal definition. I've tracked the current wording of the footnote to DR #222, , applied in Technical Corrigendum 2 after C99. In the C99 standard, the footnote says: Thus, for example, structure assignment may be implemented element-at-a-time or via memcpy. DR 222 established that structs and unions do not have trap representations. Element-at-a-time copying could cause undefined behavior if a member has a trap representation ("non-value representation" in C23). The revised footnote is a more general statement about padding. There are four kinds of "padding" that might appear within a struct (that I can think of): - Bytes between members or after the last one, typically used to satisfy alignment requirements (the standard calls these "padding bytes"); - Bits between or after bit-fields or in anonymous bit-fields; - Bits within an integer (sub)member that do not contribute to its value (the standard calls these "padding bits"); and - Bits within a pointer or floating-point (sub)member that do not contribute to its value. The standard doesn't talk about these much, but for example a pointer or floating-point assignment might result in a normalized representation in the target that differs from the representation of the source. It's plausible that the term "padding bits" in the footnote is intended to cover all of these. When I started looking into this, I assumed that "padding bits" was a defined term. If it were, then using it to refer to anything other than bits within an integer object representation, would be incorrect. Since it isn't, using the term "padding bits" more generally is perhaps slightly confusing, but not necessarily a problem. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */