Topic: When are ctor mem-initializer arguments evaluated?


Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/05/26
Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:

>b91926@fsgm01.fnal.gov (David Sachs) writes:
>
>|> Language in the C++ standard committee's working paper strongly
>|> hints, but falls short of requiring, that arguments for a mem
>|> initializer of a constructor are to be evaluated IMMEDIATELY
>|> before the initializer is executed.

I had a look at this the other day; my interpretation was that
the draft did require this.

The comments in the example in 12.7/2 certainly assume it.
So does the example in 12.6.2/7.

>|> This still leaves in limbo code like the following:
>
>|> class X
>|> {
>|>   public:
>|>   int a;
>|>   int b;
>|>   X(int i = 0) : a(i), b(a) {} // Must b == i ?
>|> };

I think the code is well-defined, and yes `b' must be initialized to
the value of `i'.

>|> Is there a sequence point that requires that the argument for the
>|> initializer of b, be the value of a AFTER it has been initialized?

Yes, each mem-initializer is a full-expression (I think this is clear
from 1.8/13-14), and there is a sequence point after the evaluation of
each full-expression (1.8/16).  Also, 12.6.2/4 says that direct base
classes are initialized in declaration order.  So each mem-initializer
must be evaluted in turn, with a sequence point at the end of each
to ensure

That is my interpretation anyhow, and the only interpretation that I
can see which is consistent with the examples in 12.7/2 and 12.6.2/7.
However, the fact that other people have different interpretations
shows that obviously the draft is not clear enough.  It ought to be
clarified.

>|> I would have preferred the resolution, opposite to the apparent
>|> intent of the committee, that there are no such sequence points.
>
>I think I would have preferred this too, but what do you do about:
>
> X::X( int i ) : b( i ) , a( b ) {}
>
>(Note that by definition, `a' is initialized before `b'.)

Here, there is IMHO a sequence point after the evaluation of `a(b)'
and before the evaluation of `b(i)'.  That example has undefined
behaviour, since `a' is initialized before `b', but

 X::X (int i ) : b( a ) , a( i ) {}

would be well-defined since a is guaranteed to be initialized
before `b(a)' is evaluated.

--
Fergus Henderson                       | I'll forgive even GNU emacs as
fjh@cs.mu.oz.au                        | long as gcc is available ;-)
http://www.cs.mu.oz.au/~fjh            |             - Linus Torvalds





Author: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/05/26
Raw View
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:

>kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:

>>b91926@fsgm01.fnal.gov (David Sachs) writes:
>>
>>|> Language in the C++ standard committee's working paper strongly
>>|> hints, but falls short of requiring, that arguments for a mem
>>|> initializer of a constructor are to be evaluated IMMEDIATELY
>>|> before the initializer is executed.

>I had a look at this the other day; my interpretation was that
>the draft did require this.

>The comments in the example in 12.7/2 certainly assume it.
>So does the example in 12.6.2/7.

Yes, but they cover only special cases. There is no explicit
statement of the general case.

>>|> This still leaves in limbo code like the following:
>>
>>|> class X
>>|> {
>>|>   public:
>>|>   int a;
>>|>   int b;
>>|>   X(int i = 0) : a(i), b(a) {} // Must b == i ?
>>|> };

>I think the code is well-defined, and yes `b' must be initialized to
>the value of `i'.

>>|> Is there a sequence point that requires that the argument for the
>>|> initializer of b, be the value of a AFTER it has been initialized?

>Yes, each mem-initializer is a full-expression (I think this is clear
>from 1.8/13-14), and there is a sequence point after the evaluation of
>each full-expression (1.8/16).  Also, 12.6.2/4 says that direct base
>classes are initialized in declaration order.  So each mem-initializer
>must be evaluted in turn, with a sequence point at the end of each
>to ensure

>That is my interpretation anyhow, and the only interpretation that I
>can see which is consistent with the examples in 12.7/2 and 12.6.2/7.
>However, the fact that other people have different interpretations
>shows that obviously the draft is not clear enough.  It ought to be
>clarified.

The language of 1.8/13-14 covers a different kind of initialization,
but only hints at something that should be explicitly stated. The
apparent intent of the committee is well indicated, but there is
nothing resembling a clear requirememnt.





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/05/28
Raw View
In article <9514618.12830@mulga.cs.mu.OZ.AU>,
Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
>
>>b91926@fsgm01.fnal.gov (David Sachs) writes:
>>
>>|> Language in the C++ standard committee's working paper strongly
>>|> hints, but falls short of requiring, that arguments for a mem
>>|> initializer of a constructor are to be evaluated IMMEDIATELY
>>|> before the initializer is executed.
>
>I had a look at this the other day; my interpretation was that
>the draft did require this.
>
>The comments in the example in 12.7/2 certainly assume it.
>So does the example in 12.6.2/7.

 I recall it was discussed and there was agreement that
there are sequence points which force the following operation:

 evaluate arguments
 call constructor
 evaluate argument for next ctor-initialiser
 call constructor
 ...

I do not recall if a vote was taken on this.

>>|> This still leaves in limbo code like the following:
>>
>>|> class X
>>|> {
>>|>   public:
>>|>   int a;
>>|>   int b;
>>|>   X(int i = 0) : a(i), b(a) {} // Must b == i ?
>>|> };
>
>I think the code is well-defined, and yes `b' must be initialized to
>the value of `i'.

 You mean you think the code _ought_ to be well defined?

>>|> Is there a sequence point that requires that the argument for the
>>|> initializer of b, be the value of a AFTER it has been initialized?
>
>Yes, each mem-initializer is a full-expression (I think this is clear
>from 1.8/13-14), and there is a sequence point after the evaluation of
>each full-expression (1.8/16).  Also, 12.6.2/4 says that direct base
>classes are initialized in declaration order.  So each mem-initializer
>must be evaluted in turn, with a sequence point at the end of each

 No. It doesn't follow. The _arguments_ to a ctor
initialiser are full expressions, the initialisation itself is not.
It cannot be -- it isn't even an expression.

 X(full-expr)

isn't an expression in

 Y() : X(full-expr) {}

The same is true for

 int i(5);

"i(5)" isn't an expression.

What is more it is important to know if the arguments of
a virtual base ctor of a class NOT the most derived class
are evaluated at all -- the ctor isn't actually called.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/05/19
Raw View
In article <3pg702$qjo@fsgm01.fnal.gov> b91926@fsgm01.fnal.gov (David
Sachs) writes:

|> Language in the C++ standard committee's working paper strongly
|> hints, but falls short of requiring, that arguments for a mem
|> initializer of a constructor are to be evaluated IMMEDIATELY
|> before the initializer is executed.

|> This still leaves in limbo code like the following:

|> class X
|> {
|>   public:
|>   int a;
|>   int b;
|>   X(int i = 0) : a(i), b(a) {} // Must b == i ?
|> };

|> Is there a sequence point that requires that the argument for the
|> initializer of b, be the value of a AFTER it has been initialized?

|> I would have preferred the resolution, opposite to the apparent
|> intent of the committee, that there are no such sequence points.

I think I would have preferred this too, but what do you do about:

 X::X( int i ) : b( i ) , a( b ) {}

(Note that by definition, `a' is initialized before `b'.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: b91926@fsgm01.fnal.gov (David Sachs)
Date: 1995/05/18
Raw View
Language in the C++ standard committee's working paper strongly
hints, but falls short of requiring, that arguments for a mem
initializer of a constructor are to be evaluated IMMEDIATELY
before the initializer is executed.

This still leaves in limbo code like the following:

class X
{
  public:
  int a;
  int b;
  X(int i = 0) : a(i), b(a) {} // Must b == i ?
};

Is there a sequence point that requires that the argument for the
initializer of b, be the value of a AFTER it has been initialized?

I would have preferred the resolution, opposite to the apparent
intent of the committee, that there are no such sequence points.