Topic: An "intermediate value" in two-phase initialization


Author: =?ISO-8859-2?Q?Andrzej_Krzemie=F1ski?= <akrzemi1@gmail.com>
Date: Tue, 22 May 2012 12:14:18 -0700 (PDT)
Raw View
Hi,
It looks like a global object (non-local variable with static storage
duration) can be initialized in two phases (not to mention the
"constant initialization"). So, there is a moment when the first phase
-- zero-initialization -- has set the variable to value 0, but the
dynamic initialization has not yet started; and at this point it may
so happen that someone attempts to read the value from such variable.
3.6.2 p3 even mentions such situation explicitly in the note and in
the example, which implies that reading such "intermediate value"
works fine (does not cause UB). The example uses word "unspecified"
which implies even stronger that if UB were involved it would have
been mentioned also.

On the other hand, my reading of a couple of paragraphs from clause 3
makes me believe that an attempt to read the "intermediate value" is a
UB. Here are the three quotes:

3.6.2 p2: "Variables with static storage duration [...] shall be
zero-initialized before any other initialization takes place."

3.8 p1: "The lifetime of an object of type T begins when: storage with
the proper alignment and size for type T is obtained, and if the
object has non-trivial initialization, its initialization is
complete."

3.8 P6: "before the lifetime of an object has started but after the
storage which the object will occupy
has been allocated [...] The program has undefined behavior if: (i) an
lvalue-to-rvalue conversion is applied to such a glvalue, (ii) the
glvalue is used to access a non-static data member".

And this is my reasoning: Until the dynamic initialization is
finished, the lifetime of the global object has not yet started. So,
an attempt to access the "intermediate value" requires either an
lvalue-to-rvalue conversion or accessing a non-static data member for
an object before its lifetime has started; which is described as UB.

So, my question is: is the reading of "intermediate (zero) value", as
described above, a well defined behavior or a UB?

Regards,
&rzej


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Bo Persson<bop@gmb.dk>
Date: Tue, 22 May 2012 14:57:35 -0700 (PDT)
Raw View
Andrzej Krzemie  ski skrev 2012-05-22 21:14:
>  Hi,
>  It looks like a global object (non-local variable with static storage
>  duration) can be initialized in two phases (not to mention the
>  "constant initialization"). So, there is a moment when the first phase
>  -- zero-initialization -- has set the variable to value 0, but the
>  dynamic initialization has not yet started; and at this point it may
>  so happen that someone attempts to read the value from such variable.
>  3.6.2 p3 even mentions such situation explicitly in the note and in
>  the example, which implies that reading such "intermediate value"
>  works fine (does not cause UB). The example uses word "unspecified"
>  which implies even stronger that if UB were involved it would have
>  been mentioned also.
>
>  On the other hand, my reading of a couple of paragraphs from clause 3
>  makes me believe that an attempt to read the "intermediate value" is a
>  UB. Here are the three quotes:
>
>  3.6.2 p2: "Variables with static storage duration [...] shall be
>  zero-initialized before any other initialization takes place."
>
>  3.8 p1: "The lifetime of an object of type T begins when: storage with
>  the proper alignment and size for type T is obtained, and if the
>  object has non-trivial initialization, its initialization is
>  complete."
>
>  3.8 P6: "before the lifetime of an object has started but after the
>  storage which the object will occupy
>  has been allocated [...] The program has undefined behavior if: (i) an
>  lvalue-to-rvalue conversion is applied to such a glvalue, (ii) the
>  glvalue is used to access a non-static data member".
>
>  And this is my reasoning: Until the dynamic initialization is
>  finished, the lifetime of the global object has not yet started. So,
>  an attempt to access the "intermediate value" requires either an
>  lvalue-to-rvalue conversion or accessing a non-static data member for
>  an object before its lifetime has started; which is described as UB.
>
>  So, my question is: is the reading of "intermediate (zero) value", as
>  described above, a well defined behavior or a UB?
>

I think you have already answered you question. For some types, those
without any "non-trivial initialization", the zero-initialization is all
there is. Those are complete and "alive" immediately. This int.

Accessing objects with non-trivial constructors before the constructor
has completed, is definitely UB.


Bo Persson


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?ISO-8859-2?Q?Andrzej_Krzemie=F1ski?= <akrzemi1@gmail.com>
Date: Thu, 24 May 2012 00:04:35 -0700 (PDT)
Raw View
W dniu wtorek, 22 maja 2012 23:57:35 UTC+2 u   ytkownik Bo Persson napisa   :
> Andrzej Krzemie   ski skrev 2012-05-22 21:14:
> >  Hi,
> >  It looks like a global object (non-local variable with static storage
> >  duration) can be initialized in two phases (not to mention the
> >  "constant initialization"). So, there is a moment when the first phase
> >  -- zero-initialization -- has set the variable to value 0, but the
> >  dynamic initialization has not yet started; and at this point it may
> >  so happen that someone attempts to read the value from such variable.
> >  3.6.2 p3 even mentions such situation explicitly in the note and in
> >  the example, which implies that reading such "intermediate value"
> >  works fine (does not cause UB). The example uses word "unspecified"
> >  which implies even stronger that if UB were involved it would have
> >  been mentioned also.
> >
> >  On the other hand, my reading of a couple of paragraphs from clause 3
> >  makes me believe that an attempt to read the "intermediate value" is a
> >  UB. Here are the three quotes:
> >
> >  3.6.2 p2: "Variables with static storage duration [...] shall be
> >  zero-initialized before any other initialization takes place."
> >
> >  3.8 p1: "The lifetime of an object of type T begins when: storage with
> >  the proper alignment and size for type T is obtained, and if the
> >  object has non-trivial initialization, its initialization is
> >  complete."
> >
> >  3.8 P6: "before the lifetime of an object has started but after the
> >  storage which the object will occupy
> >  has been allocated [...] The program has undefined behavior if: (i) an
> >  lvalue-to-rvalue conversion is applied to such a glvalue, (ii) the
> >  glvalue is used to access a non-static data member".
> >
> >  And this is my reasoning: Until the dynamic initialization is
> >  finished, the lifetime of the global object has not yet started. So,
> >  an attempt to access the "intermediate value" requires either an
> >  lvalue-to-rvalue conversion or accessing a non-static data member for
> >  an object before its lifetime has started; which is described as UB.
> >
> >  So, my question is: is the reading of "intermediate (zero) value", as
> >  described above, a well defined behavior or a UB?
> >
>
> I think you have already answered you question. For some types, those
> without any "non-trivial initialization", the zero-initialization is all
> there is. Those are complete and "alive" immediately. This int.
>
> Accessing objects with non-trivial constructors before the constructor
> has completed, is definitely UB.

But what about the cases where we have a "non-trivial initialization"
(I am probably using this term incorrectly) but no constructor
involved:

 int init_i() { return 9; }
 int i = init_i();

If I am (un)lucky to observe variable i with value 0 is this an UB?

Regards,
&rzej


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]