Groups | Search | Server Info | Login | Register


Groups > comp.lang.c > #398819

Re: Are designated initializer supposed to zero padding?

From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: Are designated initializer supposed to zero padding?
Date 2026-05-12 09:36 -0700
Organization A noiseless patient Spider
Message-ID <86bjekmvom.fsf@linuxsc.com> (permalink)
References <10tqqso$kn23$1@dont-email.me> <86jytar6n2.fsf@linuxsc.com> <10trvca$topc$1@dont-email.me>

Show all headers | View raw


highcrew <high.crew3868@fastmail.com> writes:

> Hello,
>
> On 5/11/26 5:01 AM, Tim Rentsch wrote:
>
>> highcrew <high.crew3868@fastmail.com> writes:
>>
>> You seem to be asking two different questions, one about padding
>> and one about flexible array members.  The example code is
>> incomplete, so it's hard to be sure exactly what your questions
>> are, but let me take a stab at being helpful.
>
> Yes, perhaps I was a little confusing.
> The fact the "actual" array is a struct with FAM is orthogonal.
> The interesting bit is that the whole memory chunk is zeroed
> via calloc.
>
> ...yet it was lucky that I mentioned it, so you could show
> me that neat initialization of local variable variable with FAM.
>
>> 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.
>
> OK, this is the confirmation that I was after.
>
> The problem has roots in the fact I've noticed that some compilers will
> just translate the initialization into a memset-zero or equivalent.
> But I could not find any requirement from the standard.
>
> tl;dr:
> This is of course not implying that the standard says so.  memset-zero
> is just a reasonable way to initialize all fields.
>
> Thanks for confirming it.

I'm sorry for my earlier bad answer.  It turns out that the rule
changed between C99 and C11.  In C99, a static struct with no
initializer had its padding bits set to unspecified values.  In
C11 and later, the same situation DOES set padding bits to zero.
There are some subtleties when initializing a struct when one
of its members has an initializer, and I won't try to describe
those here.  If you are interested, please read my responses to
Keith Thompson's posts.  (Again my thanks to Keith for pointing
out a key passage that I missed.)

>> Point 3:  if you want to initialize and zero a struct, along with
>> elements of a non-trivial flexible array member, probably the best
>> way to do that is as part of a union with an array of unsigned char,
>> for example as follows:
>> [...]
>>
>>     struct array *stuff =
>>        &(union {
>>           unsigned char uca[ SUITABLE_SIZE ];
>>           struct array fam;
>>        }){ .uca = { 0 } }.fam;
>>
>> assuming I haven't made any mistakes in transcription.
>>
>> Admittedly this is ugly but maybe it can be used to accomplish
>> what you want.
>
> I find that quite clean, as I said above.
>
> Thoughts:
>
> - I tried to experiment with using a struct instead of a union,
>   by having the `struct array` first and an array of items afterwards,
>   but the compiler doesn't allow that.  I suppose because that would
>   be a direct declaration of FAM struct, even if in my intention the
>   following array of items is meant as a tail to it...
>   So I understand the union is needed.  Fair enough.[1]

Yeah, it's important to use a union.

> - If I got your idea correctly, the `uca` array is initialized
>   by the `.uca = {0}` part and that is going to zero out the
>   whole padding too, since it is an array of bytes.

Exactly right.

After posting it occurred to me it would be good to wrap this
pattern in a macro.  Here is a full example:

//// start here ////

/* macros to help with declaring structs with flexible array
   members at file scope or in expressional contexts.
*/

typedef	struct {
    unsigned n;  // size of array
    char s[];    // the flexible array member
} ExampleFAMstruct;


/* the macros */

#define FAM_STRUCT_POINTER( T, id, fa_member, n, ucaname, structname )	\
  T *id = &FAM_STRUCT( T, fa_member, n, ucaname, structname )

#define	FAM_STRUCT( T, fa_member, n, ucaname, structname ) (		\
  (union {								\
    unsigned char ucaname[ FAM_STRUCT_SIZE( T, fa_member, n ) ];	\
    T structname;							\
  }){ .ucaname = { 0 } }.structname					\
)

#define FAM_STRUCT_SIZE( T, fa_member, n )  (				\
  sizeof (T) + (n) * sizeof ((T*)0)->fa_member[0]			\
)


/* an example use */

FAM_STRUCT_POINTER( ExampleFAMstruct, file_scope_p, s, 100, uca, the_struct );


#include <stdio.h>

int
main(){
  /* a second example use */
  FAM_STRUCT_POINTER( ExampleFAMstruct, p, s, 20, uca, the_struct );
    printf( "           the pointer is %p\n", (void*)p );
    printf( "the file scope pointer is %p\n", (void*)file_scope_p );
}

//// end here ////

If anyone is curious, the reason for the ucaname and structname macro
parameters it to avoid accidental collisions (even if they might be
unlikely) with names used elsewhere.  It should be easy to change the
macro definitions to take them out if they aren't wanted.


> Thanks for sharing!
>
>
> [1] side note:  I always find unions a bit ...shaky... since that day
>     I discovered how different they are in C++.  Now I don't use
>     C++ these days, but it still feels uncomfortably wonky to use
>     unions.  I have been traumatized! :P

Here is my rule of thumb for unions:

   In C, unions work.
   In C++, they don't.

Probably that isn't exactly right, but it's a good first
approximation.

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

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? 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

csiph-web