Topic: Question on the wording of static initialization


Author: Severin Ecker <severin.ecker@NO_SPAMsproing.at>
Date: Fri, 12 Mar 2010 02:11:09 CST
Raw View
Hi,

after having a clarifying discussion about the exact meanings of the
standard concerning the static/dynamic initialization of function
local/namespace scope objects with static storage duration in
comp.lang.c++ (initialization order of function local static
variables) we found a sentence which we weren't sure why it's written
that way so Alf directed me here:

The passages in question are (in C++ 2003 standard):

section 3.6.1-1 names only static initialization (= zero init. and
init. with constant expressions) and everything else which is dynamic
initialization.

On the other hand 3.6.3-1 seems to make a distinction between a
constructor call and dynamic initialization ("These objects are
destroyed in the reverse order of the completion of their constructor
or of the completion of their dynamic initialization.") Am I being
paranoid now; but isn't the invocation of a constructor a form of
dynamic initialization and so the mention of a constructor in the
sentence above would not be needed without changing the meaning.


Alf told me that in the current draft of C++0x, while most of the
paragraph has been rewritten due to threading, the passage above is
still there. So I'm wondering if there is a difference between the
invocation of a constructor and dynamic initialization.

Many thanks in advance.
cheers,
severin

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sun, 14 Mar 2010 16:06:02 CST
Raw View
On 12 Mrz., 09:11, Severin Ecker <severin.ecker@NO_SPAMsproing.at>
wrote:
> after having a clarifying discussion about the exact meanings of the
> standard concerning the static/dynamic initialization of function
> local/namespace scope objects with static storage duration in
> comp.lang.c++ (initialization order of function local static
> variables) we found a sentence which we weren't sure why it's written
> that way so Alf directed me here:
>
> The passages in question are (in C++ 2003 standard):
>
> section 3.6.1-1 names only static initialization (= zero init. and
> init. with constant expressions) and everything else which is dynamic
> initialization.
>
> On the other hand 3.6.3-1 seems to make a distinction between a
> constructor call and dynamic initialization ("These objects are
> destroyed in the reverse order of the completion of their constructor
> or of the completion of their dynamic initialization.") Am I being
> paranoid now; but isn't the invocation of a constructor a form of
> dynamic initialization and so the mention of a constructor in the
> sentence above would not be needed without changing the meaning.
>
> Alf told me that in the current draft of C++0x, while most of the
> paragraph has been rewritten due to threading, the passage above is
> still there. So I'm wondering if there is a difference between the
> invocation of a constructor and dynamic initialization.

I agree that a wording

"completion of their constructor or of the completion of their
dynamic initialization"

could be replaced by

"completion of the dynamic initialization of an object"

without any change of meaning. I learned today that
the current wording form is due to the historic
development of the standard (thanks to Mike Miller!):
The initial wording referred to constructors alone,
but it was later realized that e.g. aggregate
initialization with a dynamic component did not
require the presence of a constructor, so the part
referring to dynamic initialization was added later as
a fix. If one would refactor this part today, it would
now be possible to simplify that, but as I understand
it, there is currently no convincing reason for such a
change.

HTH & Greetings from Bremen,

Daniel Kr   gler




--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Mon, 15 Mar 2010 14:01:43 CST
Raw View
Severin Ecker wrote:

> Hi,
>
> after having a clarifying discussion about the exact meanings of the
> standard concerning the static/dynamic initialization of function
> local/namespace scope objects with static storage duration in
> comp.lang.c++ (initialization order of function local static
> variables) we found a sentence which we weren't sure why it's written
> that way so Alf directed me here:
>
> The passages in question are (in C++ 2003 standard):
>
> section 3.6.1-1 names only static initialization (= zero init. and
> init. with constant expressions) and everything else which is dynamic
> initialization.
>
> On the other hand 3.6.3-1 seems to make a distinction between a
> constructor call and dynamic initialization ("These objects are
> destroyed in the reverse order of the completion of their constructor
> or of the completion of their dynamic initialization.") Am I being
> paranoid now; but isn't the invocation of a constructor a form of
> dynamic initialization and so the mention of a constructor in the
> sentence above would not be needed without changing the meaning.
>
>
> Alf told me that in the current draft of C++0x, while most of the
> paragraph has been rewritten due to threading, the passage above is
> still there. So I'm wondering if there is a difference between the
> invocation of a constructor and dynamic initialization.
>

It looks to me that in C++0x, an object of a class with a constexpr
constructor but a non-trivial destructor could be initialized statically. So
here it would make a difference.

In C++03, 3.6.2/2 grants implementations to initialize objects statically
even if they are not required to be initialized that way, as long as the
initialization obeyes the two rules listed there, and 6.7/4 grants the same
latitude to local static objects. So here we would have a difference in
C++03 of constructor call and dynamic initialization, it seems. Not sure if
this one is legal, though.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Fri, 19 Mar 2010 14:21:51 CST
Raw View
On Mar 15, 9:01 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Severin Ecker wrote:
> > Hi,
>
> > after having a clarifying discussion about the exact meanings of the
> > standard concerning the static/dynamic initialization of function
> > local/namespace scope objects with static storage duration in
> > comp.lang.c++ (initialization order of function local static
> > variables) we found a sentence which we weren't sure why it's written
> > that way so Alf directed me here:
>
> > The passages in question are (in C++ 2003 standard):
>
> > section 3.6.1-1 names only static initialization (= zero init. and
> > init. with constant expressions) and everything else which is dynamic
> > initialization.
>
> > On the other hand 3.6.3-1 seems to make a distinction between a
> > constructor call and dynamic initialization ("These objects are
> > destroyed in the reverse order of the completion of their constructor
> > or of the completion of their dynamic initialization.") Am I being
> > paranoid now; but isn't the invocation of a constructor a form of
> > dynamic initialization and so the mention of a constructor in the
> > sentence above would not be needed without changing the meaning.
>
> > Alf told me that in the current draft of C++0x, while most of the
> > paragraph has been rewritten due to threading, the passage above is
> > still there. So I'm wondering if there is a difference between the
> > invocation of a constructor and dynamic initialization.
>
> It looks to me that in C++0x, an object of a class with a constexpr
> constructor but a non-trivial destructor could be initialized statically.

Sure.

> So here it would make a difference.

I don't see how, see below.

> In C++03, 3.6.2/2 grants implementations to initialize objects statically
> even if they are not required to be initialized that way, as long as the
> initialization obeyes the two rules listed there, and 6.7/4 grants the
same
> latitude to local static objects. So here we would have a difference in
> C++03 of constructor call and dynamic initialization, it seems. Not sure
if
> this one is legal, though.

I don't see how there could be a difference in C++0x. According to
[basic.start.term]/1:

"[..] If the completion of the constructor or dynamic initialization
of
an object with static storage duration is sequenced before that of
another, the completion of the destructor of the second is
sequenced before the initiation of the destructor of the first.
[ Note:
this definition permits concurrent destruction. =97end note ] If an
object is initialized statically, the object is destroyed in the same
order as if the object was dynamically initialized.[..]"

The last quoted sentence describes the situation you seem
to discuss and ensures that even statically initialized
objects will follow the same destroy order logic as dynamically
initialized objects. So you can simply remove the
"constructor or" part as discussed in my reply to the OP
without change of the meaning.

The latitude given to an implementation to replace dynamic
initialization by static initialization is not relevant here,
because of the restrictions described in [basic.start.init]/3.

Do you have an example in your mind where this would
cause an observable difference not relying on undefined
behavior?

As I described in the other reply: The usage of "construction"
in several parts of the standard is rather old/outdated
terminology. Newer parts and parts that are going to be
changed anyway, typically use the more general and more
correct notion of "initialization" because the latter makes
sense for e.g. aggregates and references as well.
Similar old wording can be recognized by forms like
"fully constructed".

Currently a similar replacement is searched for destroy/
destruction. The most natural term (compared to initialize/
initialization) seems to be finalize/finalization to me. I
heart opinions that this could be mixed up with Javas
meaning of  "finalize" (Personally I don't see this danger,
although I'm working with Java as well).

If you have a good naming suggestion for this situation,
it would be interesting to hear that.

Greetings from Bremen,

Daniel Kr=FCgler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 19 Mar 2010 18:10:23 CST
Raw View
=?ISO-8859-1?Q?Daniel_Kr=FCgler?= wrote:

> On Mar 15, 9:01 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> Severin Ecker wrote:
>> > Hi,
>>
>> > after having a clarifying discussion about the exact meanings of the
>> > standard concerning the static/dynamic initialization of function
>> > local/namespace scope objects with static storage duration in
>> > comp.lang.c++ (initialization order of function local static
>> > variables) we found a sentence which we weren't sure why it's written
>> > that way so Alf directed me here:
>>
>> > The passages in question are (in C++ 2003 standard):
>>
>> > section 3.6.1-1 names only static initialization (= zero init. and
>> > init. with constant expressions) and everything else which is dynamic
>> > initialization.
>>
>> > On the other hand 3.6.3-1 seems to make a distinction between a
>> > constructor call and dynamic initialization ("These objects are
>> > destroyed in the reverse order of the completion of their constructor
>> > or of the completion of their dynamic initialization.") Am I being
>> > paranoid now; but isn't the invocation of a constructor a form of
>> > dynamic initialization and so the mention of a constructor in the
>> > sentence above would not be needed without changing the meaning.
>>
>> > Alf told me that in the current draft of C++0x, while most of the
>> > paragraph has been rewritten due to threading, the passage above is
>> > still there. So I'm wondering if there is a difference between the
>> > invocation of a constructor and dynamic initialization.
>>
>> It looks to me that in C++0x, an object of a class with a constexpr
>> constructor but a non-trivial destructor could be initialized statically.
>
> Sure.
>
>> So here it would make a difference.
>
> I don't see how, see below.
>
>> In C++03, 3.6.2/2 grants implementations to initialize objects statically
>> even if they are not required to be initialized that way, as long as the
>> initialization obeyes the two rules listed there, and 6.7/4 grants the
> same
>> latitude to local static objects. So here we would have a difference in
>> C++03 of constructor call and dynamic initialization, it seems. Not sure
> if
>> this one is legal, though.
>
> I don't see how there could be a difference in C++0x. According to
> [basic.start.term]/1:
>
> "[..] If the completion of the constructor or dynamic initialization
> of
> an object with static storage duration is sequenced before that of
> another, the completion of the destructor of the second is
> sequenced before the initiation of the destructor of the first.
> [ Note:
> this definition permits concurrent destruction. =97end note ] If an
> object is initialized statically, the object is destroyed in the same
> order as if the object was dynamically initialized.[..]"
>
> The last quoted sentence describes the situation you seem
> to discuss and ensures that even statically initialized
> objects will follow the same destroy order logic as dynamically
> initialized objects. So you can simply remove the
> "constructor or" part as discussed in my reply to the OP
> without change of the meaning.
>

Ah i see. I missed that last sentence all the way. And i was thinking static
initialization is unordered in C++0x like it is in C++03, but incidentally
3.6.2 was completely reworded and i missed the stuff there too :)

> The latitude given to an implementation to replace dynamic
> initialization by static initialization is not relevant here,
> because of the restrictions described in [basic.start.init]/3.
>
> Do you have an example in your mind where this would
> cause an observable difference not relying on undefined
> behavior?
>

I'm sorry i can't find any example. Not sure what i thought of really, but
p3 actually seems to forbid all the nasty cases that don't really on UB :(


> As I described in the other reply: The usage of "construction"
> in several parts of the standard is rather old/outdated
> terminology. Newer parts and parts that are going to be
> changed anyway, typically use the more general and more
> correct notion of "initialization" because the latter makes
> sense for e.g. aggregates and references as well.
> Similar old wording can be recognized by forms like
> "fully constructed".
>

I wonder whether there is a difference between "creation" and "construction"
of an object in the current Standard? In the following within the
constructor of "A", is the object's creation complete, but its construction
not yet? Or is the completion of creation waiting for the construction to
comlete?

struct A {
   A() { /* here? */ }
};

Or are creation and construction synonymous? Is the following definition of
"n" a construction of the object? Or only a creation (as in "create" but not
"construct" (because there is no constructor)).

{
   int n;
}

Not sure i'm understanding the different concepts.

> Currently a similar replacement is searched for destroy/
> destruction. The most natural term (compared to initialize/
> initialization) seems to be finalize/finalization to me. I
> heart opinions that this could be mixed up with Javas
> meaning of  "finalize" (Personally I don't see this danger,
> although I'm working with Java as well).
>
> If you have a good naming suggestion for this situation,
> it would be interesting to hear that.
>

Why do you need to replace "destruction" something else? Do you seek for a
term that would end the lifetime of an object, but not necessarily get rid
of it? Like in the following

struct A { ~A() { } };
int main() {
   A a; a.~A();
    /* a is "finalized", but not destroyed
    (non-value operations are still allowed) */
}

For non-class objects i believe ending lifetime ("finalize") and destruction
is the same (and means getting rid of the allocated storage or reusing it
with another type).

As an example there is "Terminating the program without leaving the current
block (e.g., by calling the function std::exit(int) (18.5)) does not destroy
any objects with automatic storage duration" at 3.6.1/4. It does not forbid
the impl to call the destructor of a class type object, as long as it keeps
the memory allocated. Do you intend to replace this by "finalize" ?

I think as alternative, you could use "destruct". This is how i see them
related:

- create, created, creation: Allocate storage for an object. Do not yet
determine properties of it (such as the type) apart from its size.
- construct, constructed, construction: In case of class types, call the
constructor. Implies an already created object. Starts lifetime after
construction is complete. Afterwards, object is constructed. For non-class
and non-array-of-class types, create and construct is the same.

- destruct, destructed, destruction: In case of class types, call the
destructor. Does not necessarily free the storage it allocates, but renders
invalid properties such as the type except in the destructor. Ends lifetime
of the object. For non-class types, destruct and destroy is the same.
- destroy, destroyed, not-sure-what-comes-here: Free or reuse the storage
allocated by an object. Reuse means to use a different type to access the
object or to construct another object at this storage location (placement-
new).

Granted, the similarity between all those 4 terms is very disturbing.

I'm not really sure how the type used to denote an object by an lvalue plays
a role in current Standard, and it seems it's important to clarify it. Let's
see

     int *p = malloc(sizeof *p); // #1
     int x = *p; // #2
     float y = *(float*)p; // #3

At #1, the object is created. It has not got a type. But at "*p", the type
is assumed to be the one of the lvalue used to access it. For #3 to violate
the aliasing rule (which i think is intended), there must be some rule to
assign the type "int" to the object created at #1. But i'm not sure what
rule does that. The C Standard uses the "effective type" derived from the
lvalue used to access.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]