C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] [SC22WG14.21755] N2900 Initialization with {} and potential semantic divergence from C++ for new-to-C syntax

From: JeanHeyd Meneide <phdofthehouse_at_[hidden]>
Date: Sat, 5 Mar 2022 12:19:31 -0500
Coming back to this thread, it looks like C++ *does* zero-initialize the
padding of its bits when it uses the syntax = {};. Wording from
[dcl.init.general], paragraph 6 (http://eel.is/c++draft/dcl.init.general#6):

6 <http://eel.is/c++draft/dcl.init.general#6> To *zero-initialize*
<http://eel.is/c++draft/dcl.init.general#def:zero-initialization> an object
or reference of type T means:

   - (6.1) <http://eel.is/c++draft/dcl.init.general#6.1>
   if T is a scalar type ([basic.types.general]
   <http://eel.is/c++draft/basic.types.general#term.scalar.type>), the
   object is initialized to the value obtained by converting the integer
   literal 0 (zero) to T;84
   <http://eel.is/c++draft/dcl.init.general#footnote-84>
   - (6.2) <http://eel.is/c++draft/dcl.init.general#6.2>
   if T is a (possibly cv-qualified) non-union class type, its padding bits
   ([basic.types.general]
   <http://eel.is/c++draft/basic.types.general#term.padding.bits>) are
   initialized to zero bits and each non-static data member, each non-virtual
   base class subobject, and, if the object is not a base class subobject,
   each virtual base class subobject is zero-initialized;
   - (6.3) <http://eel.is/c++draft/dcl.init.general#6.3>
   if T is a (possibly cv-qualified) union type, its padding bits ([basic.
   types.general]
   <http://eel.is/c++draft/basic.types.general#term.padding.bits>) are
   initialized to zero bits and the object's first non-static named data
   member is zero-initialized;
   - (6.4) <http://eel.is/c++draft/dcl.init.general#6.4>
   if T is an array type, each element is zero-initialized;
   - (6.5) <http://eel.is/c++draft/dcl.init.general#6.5>
   if T is a reference type, no initialization is performed.

     6.2 and 6.3 make it pretty clear that when we use

T x = {};

     we get padding bits that are meant to be zero here, not indeterminate.
This also matches up with the wording in [dcl.init.aggr], though I am
unsure if "default member initializer" maps to zero-initialize or
default-initialize. Am I missing something? Am I interpreting the C++
wording incorrectly? It seems like C++ had padding-set-to-0 all along?

Sincerely,
JeanHeyd


On Fri, Mar 4, 2022 at 2:27 AM Jₑₙₛ Gustedt <jens.gustedt_at_[hidden]> wrote:

> Hello,
>
> on Fri, 4 Mar 2022 01:02:52 -0500 you (Hubert Tong via Liaison
> <liaison_at_[hidden]>) wrote:
>
> > On Thu, Mar 3, 2022 at 7:23 PM JeanHeyd Meneide
> > <phdofthehouse_at_[hidden]> wrote:
> >
> > > Dear Hubert,
> > >
> > > On Thu, Mar 3, 2022 at 4:53 PM Hubert Tong <
> > > hubert.reinterpretcast_at_[hidden]> wrote:
> > >
> > >> …
> > >> The net of this is that we're getting initialization for the first
> > >> member and trailing padding beyond the largest union member for
> > >> alignment purposes because "as if static storage duration" does
> > >> not provide as many guarantees as people think... (not so much of
> > >> a problem for structs without nested unions).
> > >>
> > >> I might need to open a defect for Clang's
> > >> `-ftrivial-auto-var-init=pattern` to properly restrict the padding
> > >> that is zeroed, but I really think the situation is a bit
> > >> nonsensical.
> > >
> > > I agree that the situation is non-ideal. However, I did do my
> > > best to represent your concerns to the Committee. In particular, I
> > > provided Optional Change 0 as part of the proposal. It was Optional
> > > and not part of the core proposal (therefore, it was voted on
> > > separately). The reason is because the wording in the previous
> > > revision had attempted to mandate it, and **most** individuals in
> > > the C Committee were miffed by such a departure from how unions
> > > were normally treated: it has always been first-member-init.
> >
> > I agree that Optional Change 0 is one way of approaching the gap. It
> > sounds from what you describe above that the primary objection to it
> > was how it does so.
>
> That was an important aspect, the proposed strategy and text was not
> even sound.
>
> But the other objection really was against adding yet another set of
> rules to C's initialization that would be difficult to comprehend.
>
> > An alternative method would be to adjust the
> > static initialization wording (with WG 21 coordination) to clarify
> > that (a) the representation of the value converted from 0 that is
> > chosen for each scalar type is consistent for all such initialization
> > of an object of that type, (b) all padding bits between members of a
> > structure and all trailing padding in a structure is zeroed, and (c)
> > all bytes of a union that do not overlap with the object
> > representation of the first member of the union are zeroed.
>
> I would be very much in favor of this, but I think this is too late
> for C23. It would be a normative change and would potentially impose
> some implementations to change. We don't even have a good overview
> what the current practice is. Platforms that have zero-bit
> representations of floating point zeroes and of null pointers probably
> always initialize by all bit zero. But for the others, I would have no
> idea what they are doing for real, here.
>
> Thanks
> Jₑₙₛ
>
> --
> :: INRIA Nancy Grand Est ::: Camus ::::::: ICube/ICPS :::
> :: ::::::::::::::: office Strasbourg : +33 368854536 ::
> :: :::::::::::::::::::::: gsm France : +33 651400183 ::
> :: ::::::::::::::: gsm international : +49 15737185122 ::
> :: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::
>

Received on 2022-03-05 17:19:45