Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Are designated initializer supposed to zero padding? Date: Tue, 12 May 2026 06:44:19 -0700 Organization: A noiseless patient Spider Lines: 85 Message-ID: <86jyt8n3nw.fsf@linuxsc.com> References: <10tqqso$kn23$1@dont-email.me> <86jytar6n2.fsf@linuxsc.com> <20260511232247.00006c5e@yahoo.com> <86wlx9pp10.fsf@linuxsc.com> <10ttnl3$1g54p$2@kst.eternal-september.org> <86lddppgze.fsf@linuxsc.com> <10ttvo6$1irrv$1@kst.eternal-september.org> <86zf25nrym.fsf@linuxsc.com> <10tukoj$1p7o0$1@kst.eternal-september.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Tue, 12 May 2026 13:44:24 +0000 (UTC) Injection-Info: dont-email.me; logging-data="2105064"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+VxPzj8D04XOB9I3XopWuFDhsCKTNpQ10="; posting-host="714746643ff61f997ea29d517f63563d" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:lTSNUGkXiAo4Eyb9OdDb64b9tRU= sha1:Hx/74FgKF/m8nL+cWffgPjJKeaQ= sha256:cZJMvfP0hcg3wpZCOi/YsC0L1ewT9d4EQs/U0JjyAHg= sha1:Q1xw5VAD7Q3voT1zlTdvd1dgbAY= Xref: csiph.com comp.lang.c:398809 Keith Thompson writes: > Tim Rentsch writes: > >> Keith Thompson writes: > > [...] > >>> In my example in the other post, I have an outer struct with an >>> inner struct as one of its members, and an object defined with an >>> initializer that doesn't explicitly initialize all its members. >>> I can derive from the wording in N3220 that any padding between >>> members of the inner struct are set to zero bits, but not that this >>> is done for padding between members in the outer struct. >> >> Okay, I understand now what you're asking about. Just a couple of >> small detours before getting to your question. >> >> First, I have confirmed that the change to the C standard about >> zeroing padding bits was made in C11, and was not present in C99. >> >> Second, I agree with your conclusion that a contained struct or >> union that has not been initialized explicitly must have any >> padding set to all zero bits. >> >> Third, as best I can determine, the rules under N3220 have the same >> meaning as the corresponding rules in C11, of course modulo some >> parts of C23 that were added after C11 and are not part of N1570. >> >> Now for the question. Given this type definition: >> >> typedef struct { struct { char c; short s; } inner; long k; } Outer; >> >> and a subsequent declaration >> >> Outer outer = { .k = 1 }; >> >> we agree that any padding in outer.inner will have been initialized >> to all zero bits, but what about padding in outer (and outside of >> outer.inner)? >> >> My reading of N3220, which coincides with my reading of N1570, is >> that the bytes of the object representation of outer that correspond >> to padding bytes (of outer) take unspecified values. That result is >> consistent with 6.2.6.1 paragraph 6, and I don't seen anything in >> N3220's 6.7.11 (which is 6.7.9 in N1570) that overrides that or that >> contradicts it. >> >> I don't see anything in either standard that talks about padding >> bits (as opposed to padding bytes) that occur as the result of >> bitfields. Presumbly padding bits (in structs and unions) get the >> same treatment as padding bytes: set to zero if their containing >> struct or union is not initialized, and given unspecified values if >> any member is initialized. > > The standard uses the term "padding bits" to mostly refer to bits > within an integer representation that do not contribute to its value. > I speculate that that section did not intend to talk about how those > bits are initialized. But the term could also apply to extra bits > between bit-fields. The phrase "padding bits" is used in connection both with struct and union types and with integer types. Where the C standard says, about struct and union types, that "any padding is initialized to zero bits", presumably that is meant to apply both to padding caused by ordinary members and to padding caused by bit-field members. I see no reason to suppose it applies only to one and not the other. > I have mixed feelings about the fact that you agree with my > interpretation, that padding (bytes) is set to zero in nested > structs but not necessarily in an outermost struct. I speculate > that that was unintentional. I can't think of any good reason > to have such a rule intentionally. For the same reason that assigning to a struct or union member gives padding unspecified values. Initializing individual members is very much like a series of assignments to those members; the semantics are more symmetric if assignment and initialization are treated the same way in the two situations. Conversely, if the rules were not the same in the two cases, the language would be less consistent. Obviously, unless there is some specific reason not to be, being more consistent it better. Initializing individual members is like assignment; default initialization is not like assignment. It is because of this difference that it makes sense to treat the two cases differently.