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.