Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #398672 > unrolled thread

Are designated initializer supposed to zero padding?

Started byhighcrew <high.crew3868@fastmail.com>
First post2026-05-10 22:47 +0200
Last post2026-05-12 01:00 +0300
Articles 11 on this page of 31 — 8 participants

Back to article view | Back to comp.lang.c


Contents

  Are designated initializer supposed to zero padding? highcrew <high.crew3868@fastmail.com> - 2026-05-10 22:47 +0200
    Re: Are designated initializer supposed to zero padding? James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-10 19:15 -0400
      Re: Are designated initializer supposed to zero padding? highcrew <high.crew3868@fastmail.com> - 2026-05-11 09:11 +0200
        Re: Are designated initializer supposed to zero padding? James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-05-12 16:02 -0400
          Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-12 21:10 -0700
            Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-13 15:51 -0700
              Re: Are designated initializer supposed to zero padding? David Brown <david.brown@hesbynett.no> - 2026-05-14 11:36 +0200
                Re: Are designated initializer supposed to zero padding? Richard Harnden <richard.nospam@gmail.invalid> - 2026-05-14 11:47 +0100
                  Re: Are designated initializer supposed to zero padding? David Brown <david.brown@hesbynett.no> - 2026-05-14 14:11 +0200
                Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-14 15:55 -0700
                  Re: Are designated initializer supposed to zero padding? David Brown <david.brown@hesbynett.no> - 2026-05-15 10:20 +0200
    Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-10 20:01 -0700
      Re: Are designated initializer supposed to zero padding? highcrew <high.crew3868@fastmail.com> - 2026-05-11 09:10 +0200
        Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-12 09:36 -0700
      Re: Are designated initializer supposed to zero padding? scott@slp53.sl.home (Scott Lurndal) - 2026-05-11 15:34 +0000
        Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 18:23 -0700
      Re: Are designated initializer supposed to zero padding? Michael S <already5chosen@yahoo.com> - 2026-05-11 23:22 +0300
        Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-11 14:34 -0700
          Re: Are designated initializer supposed to zero padding? Michael S <already5chosen@yahoo.com> - 2026-05-12 00:55 +0300
            Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 15:27 -0700
            Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-11 16:07 -0700
        Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 15:19 -0700
          Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-11 16:10 -0700
            Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 18:13 -0700
              Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-11 18:28 -0700
                Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 21:59 -0700
                  Re: Are designated initializer supposed to zero padding? David Brown <david.brown@hesbynett.no> - 2026-05-12 09:15 +0200
                  Re: Are designated initializer supposed to zero padding? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-05-12 00:27 -0700
                    Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-12 06:44 -0700
        Re: Are designated initializer supposed to zero padding? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-05-11 18:15 -0700
    Re: Are designated initializer supposed to zero padding? Michael S <already5chosen@yahoo.com> - 2026-05-12 01:00 +0300

Page 2 of 2 — ← Prev page 1 [2]


#398785

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-05-11 16:07 -0700
Message-ID<10ttnek$1g54p$1@kst.eternal-september.org>
In reply to#398780
Michael S <already5chosen@yahoo.com> writes:
[...]
> In this draft it is less clear. Let's look at N2310,6.7.9:

N2310 is a C2x working draft from 2018.  N3220 is the newest publicly
available C23 draft.  (The C23 standard itself is expensive.)
I'll refer to the latter in the following.

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf

> On one hand, we have 10+19:
>
> If an object that has automatic storage duration is not initialized
> explicitly, its value is indeterminate.
> If an object that has static or thread storage duration is not
> initialized explicitly, then:
> — if it has pointer type, it is initialized to a null pointer;
> — if it has arithmetic type, it is initialized to (positive or
> unsigned) zero;
> — if it is an aggregate, every member is initialized (recursively)
> according to these rules, and any padding is initialized to zero bits;
> — if it is a union, the first named member is initialized (recursively)
> according to these rules, and any padding is initialized to zero bits;

Right, all that is part of the definition of "default initialization".
It applies to objects with static or thread storage duration with
no initalizer, or to any object with an empty initializer, and
in some other contexts.

> The initialization shall occur in initializer list order, each
> initializer provided for a particular subobject overriding any
> previously listed initializer for the same subobject) all subobjects
> that are not initialized explicitly shall be initialized implicitly the
> same as objects that have static storage duration.
>
> It sounds like zeroing of padding is required.

N3220 changed this a bit.  It says:

    The initialization shall occur in initializer list order, each
    initializer provided for a particular subobject overriding
    any previously listed initializer for the same subobject; all
    subobjects that are not initialized explicitly are subject to
    default initialization.

Default initialization implies that padding is set to zero bits -- but
it appears to apply to subobjects, not to the top-level object.
My reading (which I suspect doesn't match the intent) is that, given:

    struct inner {
        char c_inner;
        // probably padding here
        int i;
    };
    struct outer {
        char c_outer;
        // probably padding here
        struct inner inn;
    };
    struct outer foo = { .c = '?' };

foo.c_outer is of course set to '?'.  foo.inn, because it's a
subobject, has its padding set to zero bits; foo.inn.c_inner and
foo.inn.i are set to 0 by default initialization.  But I don't see
a requirement for setting foo's padding to zero bits.  (The padding
is not a subobject.)

It would make more sense to say that *all* padding is set to zero
bits, but I don't see that stated in N3220.

> On the other hand, we have 9:
> Except where explicitly stated otherwise, for the purposes of this
> subclause unnamed members of objects of structure and union type do not
> participate in initialization. Unnamed members of structure objects
> have indeterminate value even after initialization.
>
> It sounds like zeroing of padding is not required.

Maybe, but see the "Except where explicitly stated otherwise"
clause.  Unnamed members are subobjects, are subject to default
initialization.  As Tim points out, unnamed members and padding
are two different things.

> It's quite confusing.

Agreed.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#398783

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-11 15:19 -0700
Message-ID<86wlx9pp10.fsf@linuxsc.com>
In reply to#398767
Michael S <already5chosen@yahoo.com> writes:

> On Sun, 10 May 2026 20:01:53 -0700
> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> Point 1:  initializers are not required to set padding (either
>> padding bits or padding bytes).  Don't expect padding to be
>> zeroed.  This statement applies to initializers in all forms -
>> regular initializers, designated initializers, and compound
>> literals.
>
> James Kuyper says that zeroing of padding is required by that standard.
> I am not an expert in lawyer-style reading of the standard, but at my
> level it looks that he is correct and the wording in unequivocal.
> For example, n3220, 6.7.11:
>
> 11
> If an object that has automatic storage duration is not initialized
> explicitly, its representation is indeterminate.  If an object that has
> static or thread storage duration is not initialized explicitly, or
> any object is initialized with an empty initializer, then it is subject
> to default initialization, which initializes an object as follows:
> ? if it has pointer type, it is initialized to a null pointer;
> ? if it has decimal floating type, it is initialized to positive zero,
> and the quantum exponent is implementation-defined;
> ? if it has arithmetic type, and it does not have decimal floating
> type, it is initialized to (positive or unsigned) zero;
> ? if it is an aggregate, every member is initialized (recursively)
> according to these rules, and any padding is initialized to zero bits;

The problem is padding is none of those things.  Padding

  (1) does not have pointer type;
  (2) does not have decimal floating type;
  (3) does not have arithmetic type;
  (4) is not a struct, a union, or an array;
  (5) is not a member of any struct or union;
  (6) is not an element of any array;  and
  (7) is not an object, as the C standard uses the term.

To see these are true, for 1 to 6, it's enough to note that
all of them have a type.  Padding does not have a type.

For number 7, the C standard defines object as a region of storage,
the contents of which can hold values.  To hold a value, an object
has to have a type.  Padding does not have a type.

We can see from other parts of the C standard that it doesn't
consider padding to be objects.  In 6.2.6.1 paragraph 6, the C
standard says

   When a value is stored in an object of struct or union type,
   including in a member object, the bytes of the object
   representation that correspond to any padding bytes take
   unspecified values

Note the wording used:  the text doesn't talk about padding objects,
it says "the bytes of the object representation that correspond to
any padding bytes".  The C standard doesn't consider the space
occupied by padding to be an object, or a subobject of the struct or
union surrounding it.

For that matter, initializing a struct or a union stores a value
in it.  By the paragraph quoted above, any padding bytes take
unspecified values.  So not necessarily zero.

Of course there is nothing stopping an implementation from setting
all the padding bytes (and padding bits, if there are any) to zero;
but the C standard does not require it.

[toc] | [prev] | [next] | [standalone]


#398786

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-05-11 16:10 -0700
Message-ID<10ttnl3$1g54p$2@kst.eternal-september.org>
In reply to#398783
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Michael S <already5chosen@yahoo.com> writes:
>
>> On Sun, 10 May 2026 20:01:53 -0700
>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>
>>> Point 1:  initializers are not required to set padding (either
>>> padding bits or padding bytes).  Don't expect padding to be
>>> zeroed.  This statement applies to initializers in all forms -
>>> regular initializers, designated initializers, and compound
>>> literals.
>>
>> James Kuyper says that zeroing of padding is required by that standard.
>> I am not an expert in lawyer-style reading of the standard, but at my
>> level it looks that he is correct and the wording in unequivocal.
>> For example, n3220, 6.7.11:
>>
>> 11
>> If an object that has automatic storage duration is not initialized
>> explicitly, its representation is indeterminate.  If an object that has
>> static or thread storage duration is not initialized explicitly, or
>> any object is initialized with an empty initializer, then it is subject
>> to default initialization, which initializes an object as follows:
>> ? if it has pointer type, it is initialized to a null pointer;
>> ? if it has decimal floating type, it is initialized to positive zero,
>> and the quantum exponent is implementation-defined;
>> ? if it has arithmetic type, and it does not have decimal floating
>> type, it is initialized to (positive or unsigned) zero;
>> ? if it is an aggregate, every member is initialized (recursively)
>> according to these rules, and any padding is initialized to zero bits;
>
> The problem is padding is none of those things.

Um, padding is padding.  "... and any padding is initialized to zero
bits".

As I wrote elsethread, it seems clear that padding within subobjects
(except for automatic objects with no initializer) is set to zero bits.
I haven't found wording that applies that to top-level padding.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#398788

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-11 18:13 -0700
Message-ID<86lddppgze.fsf@linuxsc.com>
In reply to#398786
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Michael S <already5chosen@yahoo.com> writes:
>>
>>> On Sun, 10 May 2026 20:01:53 -0700
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>
>>>> Point 1:  initializers are not required to set padding (either
>>>> padding bits or padding bytes).  Don't expect padding to be
>>>> zeroed.  This statement applies to initializers in all forms -
>>>> regular initializers, designated initializers, and compound
>>>> literals.
>>>
>>> James Kuyper says that zeroing of padding is required by that standard.
>>> I am not an expert in lawyer-style reading of the standard, but at my
>>> level it looks that he is correct and the wording in unequivocal.
>>> For example, n3220, 6.7.11:
>>>
>>> 11
>>> If an object that has automatic storage duration is not initialized
>>> explicitly, its representation is indeterminate.  If an object that has
>>> static or thread storage duration is not initialized explicitly, or
>>> any object is initialized with an empty initializer, then it is subject
>>> to default initialization, which initializes an object as follows:
>>> ? if it has pointer type, it is initialized to a null pointer;
>>> ? if it has decimal floating type, it is initialized to positive zero,
>>> and the quantum exponent is implementation-defined;
>>> ? if it has arithmetic type, and it does not have decimal floating
>>> type, it is initialized to (positive or unsigned) zero;
>>> ? if it is an aggregate, every member is initialized (recursively)
>>> according to these rules, and any padding is initialized to zero bits;
>>
>> The problem is padding is none of those things.
>
> Um, padding is padding.  "... and any padding is initialized to zero
> bits".

Sorry, I stand corrected.  It looks like this change was made as
part of C11.  So in C99 padding is not initialized to zeros, and
in C11 and later it is.

> As I wrote elsethread, it seems clear that padding within subobjects
> (except for automatic objects with no initializer) is set to zero bits.
> I haven't found wording that applies that to top-level padding.

What does it mean to talk about top-level padding?  Isn't it the
case that padding (not counting padding bits in arithmetic types)
occurs only in structs and unions?  Can you give an example of a
declaration where "top-level padding" occurs?

I should add that I haven't yet read the other post where you
talk about this.

[toc] | [prev] | [next] | [standalone]


#398792

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-05-11 18:28 -0700
Message-ID<10ttvo6$1irrv$1@kst.eternal-september.org>
In reply to#398788
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>> Michael S <already5chosen@yahoo.com> writes:
>>>> On Sun, 10 May 2026 20:01:53 -0700
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>>
>>>>> Point 1:  initializers are not required to set padding (either
>>>>> padding bits or padding bytes).  Don't expect padding to be
>>>>> zeroed.  This statement applies to initializers in all forms -
>>>>> regular initializers, designated initializers, and compound
>>>>> literals.
>>>>
>>>> James Kuyper says that zeroing of padding is required by that standard.
>>>> I am not an expert in lawyer-style reading of the standard, but at my
>>>> level it looks that he is correct and the wording in unequivocal.
>>>> For example, n3220, 6.7.11:
>>>>
>>>> 11
>>>> If an object that has automatic storage duration is not initialized
>>>> explicitly, its representation is indeterminate.  If an object that has
>>>> static or thread storage duration is not initialized explicitly, or
>>>> any object is initialized with an empty initializer, then it is subject
>>>> to default initialization, which initializes an object as follows:
>>>> ? if it has pointer type, it is initialized to a null pointer;
>>>> ? if it has decimal floating type, it is initialized to positive zero,
>>>> and the quantum exponent is implementation-defined;
>>>> ? if it has arithmetic type, and it does not have decimal floating
>>>> type, it is initialized to (positive or unsigned) zero;
>>>> ? if it is an aggregate, every member is initialized (recursively)
>>>> according to these rules, and any padding is initialized to zero bits;
>>>
>>> The problem is padding is none of those things.
>>
>> Um, padding is padding.  "... and any padding is initialized to zero
>> bits".
>
> Sorry, I stand corrected.  It looks like this change was made as
> part of C11.  So in C99 padding is not initialized to zeros, and
> in C11 and later it is.
>
>> As I wrote elsethread, it seems clear that padding within subobjects
>> (except for automatic objects with no initializer) is set to zero bits.
>> I haven't found wording that applies that to top-level padding.
>
> What does it mean to talk about top-level padding?  Isn't it the
> case that padding (not counting padding bits in arithmetic types)
> occurs only in structs and unions?  Can you give an example of a
> declaration where "top-level padding" occurs?
>
> I should add that I haven't yet read the other post where you
> talk about this.

By "top-level padding", I mean padding between members of the named
object being initialized, as opposed to padding in subobjects.
(Similar considerations apply to unions.)

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.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#398798

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-11 21:59 -0700
Message-ID<86zf25nrym.fsf@linuxsc.com>
In reply to#398792
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>
>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>
>>>> Michael S <already5chosen@yahoo.com> writes:
>>>>
>>>>> On Sun, 10 May 2026 20:01:53 -0700
>>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>>>>>
>>>>>> Point 1:  initializers are not required to set padding (either
>>>>>> padding bits or padding bytes).  Don't expect padding to be
>>>>>> zeroed.  This statement applies to initializers in all forms -
>>>>>> regular initializers, designated initializers, and compound
>>>>>> literals.
>>>>>
>>>>> James Kuyper says that zeroing of padding is required by that standard.
>>>>> I am not an expert in lawyer-style reading of the standard, but at my
>>>>> level it looks that he is correct and the wording in unequivocal.
>>>>> For example, n3220, 6.7.11:
>>>>>
>>>>> 11
>>>>> If an object that has automatic storage duration is not initialized
>>>>> explicitly, its representation is indeterminate.  If an object that has
>>>>> static or thread storage duration is not initialized explicitly, or
>>>>> any object is initialized with an empty initializer, then it is subject
>>>>> to default initialization, which initializes an object as follows:
>>>>> ? if it has pointer type, it is initialized to a null pointer;
>>>>> ? if it has decimal floating type, it is initialized to positive zero,
>>>>> and the quantum exponent is implementation-defined;
>>>>> ? if it has arithmetic type, and it does not have decimal floating
>>>>> type, it is initialized to (positive or unsigned) zero;
>>>>> ? if it is an aggregate, every member is initialized (recursively)
>>>>> according to these rules, and any padding is initialized to zero bits;
>>>>
>>>> The problem is padding is none of those things.
>>>
>>> Um, padding is padding.  "... and any padding is initialized to zero
>>> bits".
>>
>> Sorry, I stand corrected.  It looks like this change was made as
>> part of C11.  So in C99 padding is not initialized to zeros, and
>> in C11 and later it is.
>>
>>> As I wrote elsethread, it seems clear that padding within subobjects
>>> (except for automatic objects with no initializer) is set to zero bits.
>>> I haven't found wording that applies that to top-level padding.
>>
>> What does it mean to talk about top-level padding?  Isn't it the
>> case that padding (not counting padding bits in arithmetic types)
>> occurs only in structs and unions?  Can you give an example of a
>> declaration where "top-level padding" occurs?
>>
>> I should add that I haven't yet read the other post where you
>> talk about this.
>
> By "top-level padding", I mean padding between members of the named
> object being initialized, as opposed to padding in subobjects.
> (Similar considerations apply to unions.)
>
> 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.

In C23, my understanding is "default initialization" is the same as
what initialization is done for static objects with no initializer;
which is to say, the declared (sub)object is initialized, but not
with an explicit initializer (and thus padding in structs or unions
with a default initializer must be set to zero).

I haven't tried to answer the question of what happens when a struct
or union is initialized as a whole, by assignment.  For example, if
we have

  typedef struct { struct { char c; short s; } inner; long k; } Outer;
  Outer foo = (Outer){ .k = 1 };

I haven't tried to find out whether foo.inner might be allowed to
have non-zero padding bytes.  I think an argument could be made
either way, but I haven't spent any time trying to really track it
down.  In C99 it seems clear that any padding is unspecified, so
erring on the side of caution it's probably best to assume that.

Thank you for the correction upstream about rules for initializing
padding.

[toc] | [prev] | [next] | [standalone]


#398800

FromDavid Brown <david.brown@hesbynett.no>
Date2026-05-12 09:15 +0200
Message-ID<10tuk2n$1msfu$1@dont-email.me>
In reply to#398798
On 12/05/2026 06:59, Tim Rentsch wrote:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
> 
>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>
>>>> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>>>>
>>>>> Michael S <already5chosen@yahoo.com> writes:
>>>>>
<snip>
>>>>>> 11
>>>>>> If an object that has automatic storage duration is not initialized
>>>>>> explicitly, its representation is indeterminate.  If an object that has
>>>>>> static or thread storage duration is not initialized explicitly, or
>>>>>> any object is initialized with an empty initializer, then it is subject
>>>>>> to default initialization, which initializes an object as follows:
>>>>>> ? if it has pointer type, it is initialized to a null pointer;
>>>>>> ? if it has decimal floating type, it is initialized to positive zero,
>>>>>> and the quantum exponent is implementation-defined;
>>>>>> ? if it has arithmetic type, and it does not have decimal floating
>>>>>> type, it is initialized to (positive or unsigned) zero;
>>>>>> ? if it is an aggregate, every member is initialized (recursively)
>>>>>> according to these rules, and any padding is initialized to zero bits;
>>>>>
>>>>> The problem is padding is none of those things.
>>>>
>>>> Um, padding is padding.  "... and any padding is initialized to zero
>>>> bits".
>>>
>>> Sorry, I stand corrected.  It looks like this change was made as
>>> part of C11.  So in C99 padding is not initialized to zeros, and
>>> in C11 and later it is.
>>>
<snip>
> 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.
> 
I note that there is nothing in the list of "major" changes in C11 that 
reference this change.  That may mean that the standards committee saw 
this as a change of wording for clarification, rather than a change in 
specified behaviour.  Or it may just mean they did not consider it 
important enough to get a line by itself - perhaps it considered part of 
the standardisation of anonymous structures and unions (which does make 
the list of major changes).

[toc] | [prev] | [next] | [standalone]


#398801

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-05-12 00:27 -0700
Message-ID<10tukoj$1p7o0$1@kst.eternal-september.org>
In reply to#398798
Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> 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.

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.

[...]

> Thank you for the correction upstream about rules for initializing
> padding.

My pleasure.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#398809

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-12 06:44 -0700
Message-ID<86jyt8n3nw.fsf@linuxsc.com>
In reply to#398801
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> 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.

[toc] | [prev] | [next] | [standalone]


#398789

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2026-05-11 18:15 -0700
Message-ID<86h5odpgvt.fsf@linuxsc.com>
In reply to#398767
Michael S <already5chosen@yahoo.com> writes:

> On Sun, 10 May 2026 20:01:53 -0700
> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>
>> Point 1:  initializers are not required to set padding (either
>> padding bits or padding bytes).  Don't expect padding to be
>> zeroed.  This statement applies to initializers in all forms -
>> regular initializers, designated initializers, and compound
>> literals.
>
> James Kuyper says that zeroing of padding is required by that standard.
> I am not an expert in lawyer-style reading of the standard, but at my
> level it looks that he is correct and the wording in unequivocal.
> For example, n3220, 6.7.11:
>
> 11
> If an object that has automatic storage duration is not initialized
> explicitly, its representation is indeterminate.  If an object that has
> static or thread storage duration is not initialized explicitly, or
> any object is initialized with an empty initializer, then it is subject
> to default initialization, which initializes an object as follows:
> ? if it has pointer type, it is initialized to a null pointer;
> ? if it has decimal floating type, it is initialized to positive zero,
> and the quantum exponent is implementation-defined;
> ? if it has arithmetic type, and it does not have decimal floating
> type, it is initialized to (positive or unsigned) zero;
> ? if it is an aggregate, every member is initialized (recursively)
> according to these rules, and any padding is initialized to zero bits;

Sorry, I had missed the crucial last part here, even after I had
looked in multiple editions of the C standard.  Mea culpa.  Please
see my response to Keith Thompson.

[toc] | [prev] | [next] | [standalone]


#398781

FromMichael S <already5chosen@yahoo.com>
Date2026-05-12 01:00 +0300
Message-ID<20260512010023.0000651e@yahoo.com>
In reply to#398672
On Sun, 10 May 2026 22:47:20 +0200
highcrew <high.crew3868@fastmail.com> wrote:

<snip>

The question is interesting from theoretical perspective.
However from practical perspective the answer is 'better safe than
sorry'.
But you probably know it.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c


csiph-web