Topic: Is this really defined in C++?


Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Wed, 29 Sep 1993 09:22:22 GMT
Raw View
In article <ATTILA.93Sep22190535@afrodite.symsoft.se> attila@symsoft.se (Attila Nemeth) writes:
>
>
>Assume the following piece of code:
>
>class Foo {
>
>  public:
>    Foo(int i) : fie(i++), fum(i++) {};
>
>  private:
>    int fum;
>    int fie;
>};
>
>main () {
>
>    Foo a(17);
>}
>
>
>The order the variables will be initialized is of course the declaration
>order. So fum will be *initialized* before fie.
>
>Is it defined in the language in what order the member initialization list
>is *evaluated*? Thus, is it possible to say what value the variables will
>contain? May the evaluation order be different than the initialization
>order?
>
>What does the ANSI committee say about this?

The issue is one of so-called "sequence points" and, in particular, whether
or not sequences points exist within a mem-initializer list, and if so,
where.

To the best of my knowledge, the X3J16 C++ standardization committee has
yet to address sequence point in any way.  (If anyone has more up-to-date
information than I do, please post a summary of the recent X3J16 actions
with respect to sequence points.  Thanks.)

Follow-ups to comp.std.c++ please.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: kanze@us-es.sel.de (James Kanze)
Date: 30 Sep 93 12:29:35
Raw View
In article <1993Sep29.100702.20159@lulea.trab.se> jbn@lulea.trab.se
(Johan Bengtsson) writes:

|> David Sachs (b91926@fnclub.fnal.gov) wrote:

|> : Unfortunately, there is apparently much real world code like the following (as
|> sume everything in the above example except for the constructor):

|> : ...
|> : Foo(int i) : fum(i), fee(fum) {}; // does this initialize fee to i ????
|> : ...

|> : Is there any requirement that the value of fum, that is used to initialize fee
|> , not be evaluated until fum is initialized to i?

|> That depends on the order of declaration of the "fee" and "fum" members
|> in the class definition, as any decent C++ book will tell you.

Even with the correct class order, I know of no guarentee that this
will work.

The ARM doesn't use the notion of sequence points.  I believe that we
are justified in supposing that the sequence points in C are still
valid.  But the C standard doesn't say anything about where the
sequence points are in class initializations:-).

As things stand, I don't think you could call it a bug if a compiler
pushed 'fum' (not yet initialized) on the stack, then pushed 'i', and
initialized 'fum' and 'fee' with the values on the stack.

|> : I can really see nothing between decalaring code like the line above
|> : to be undefined and strictly defining the effect of code that properly
|> : belongs in an obfuscated c++ contest.

|> I agree that depending on the declaration order of data members is
|> asking for trouble, and in fact it would be preferable for the
|> compiler to warn about member initializers being given in any
|> other order than the declaration order.

I believe that some compilers actually issue a warning in such cases.

And I hope that the standards committee will declare that there is a
sequence point between each initialization.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung




Author: rsousa@gamera.NoSubdomain.NoDomain (Ray Sousa)
Date: 30 Sep 1993 17:14:45 GMT
Raw View
In article <KANZE.93Sep30122935@slsvhdt.us-es.sel.de>, kanze@us-es.sel.de (James Kanze) writes:
|> In article <1993Sep29.100702.20159@lulea.trab.se> jbn@lulea.trab.se
|> (Johan Bengtsson) writes:
|>
|> |> David Sachs (b91926@fnclub.fnal.gov) wrote:
|>
|> |> : Unfortunately, there is apparently much real world code like the following (as
|> |> sume everything in the above example except for the constructor):
|>
|> |> : ...
|> |> : Foo(int i) : fum(i), fee(fum) {}; // does this initialize fee to i ????
|> |> : ...
|>
|> |> : Is there any requirement that the value of fum, that is used to initialize fee
|> |> , not be evaluated until fum is initialized to i?
|>
|> |> That depends on the order of declaration of the "fee" and "fum" members
|> |> in the class definition, as any decent C++ book will tell you.
|>
|> Even with the correct class order, I know of no guarentee that this
|> will work.
|>
|> The ARM doesn't use the notion of sequence points.  I believe that we
|> are justified in supposing that the sequence points in C are still
|> valid.  But the C standard doesn't say anything about where the
|> sequence points are in class initializations:-).
|>

|> --
|> James Kanze                             email: kanze@us-es.sel.de
|> GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
|> Conseils en informatique industrielle --
|>                    -- Beratung in industrieller Datenverarbeitung


The September issue of "C++ Report" discusses this.  According to the
answer given there, the ISO/ANSI standards committee has not reached a
decision on it.  Currently, it is not defined.  The discussion is
on pages 8 and 10 in the "C++ Oracle" column.


--------------------------------------------------------------------

Ray S. Sousa    email: rsousa@ctron.com   or
Cabletron Systems                              seuss@mv.mv.com
Merrimack, N.H.

"Humpty Dumpty was pushed." -- Anonymous




Author: ghica@fig.citib.com (Renato Ghica)
Date: Thu, 30 Sep 1993 21:13:12 GMT
Raw View
In article <KANZE.93Sep30122935@slsvhdt.us-es.sel.de>, kanze@us-es.sel.de (James Kanze) writes:
|> In article <1993Sep29.100702.20159@lulea.trab.se> jbn@lulea.trab.se
|> (Johan Bengtsson) writes:
|>
|> |> David Sachs (b91926@fnclub.fnal.gov) wrote:
|>
|> |> : Unfortunately, there is apparently much real world code like the following (as
|> |> sume everything in the above example except for the constructor):
|>
|> |> : ...
|> |> : Foo(int i) : fum(i), fee(fum) {}; // does this initialize fee to i ????
|> |> : ...
|>
|> |> : Is there any requirement that the value of fum, that is used to initialize fee
|> |> , not be evaluated until fum is initialized to i?
|>
|> |> That depends on the order of declaration of the "fee" and "fum" members
|> |> in the class definition, as any decent C++ book will tell you.
|>
|> Even with the correct class order, I know of no guarentee that this
|> will work.
|>
|> The ARM doesn't use the notion of sequence points.  I believe that we
|> are justified in supposing that the sequence points in C are still
|> valid.  But the C standard doesn't say anything about where the
|> sequence points are in class initializations:-).
|>

Aren't the variables initialized in the order that they were declared, no
matter how you initializes then the constructor line?

so if we had

class Foo {
 int fum;
 int fee;
 Foo(int i) : fum(i), fee(fum) {}
..
};

then

Foo x(5) would work.

and if we had

class Foo {
 int fee;
 int fum;
 Foo(int i) : fum(i), fee(fum) {}
..
};

Foo x(5) wouldn't, because fum is not defined when fee is initialized?

-rg
--

[the opinions above are my own!]
"die,die, damned thread!"
"delete *this"




Author: kanze@us-es.sel.de (James Kanze)
Date: 1 Oct 93 12:34:53
Raw View
In article <CE6qy0.DJp@fig.citib.com> ghica@fig.citib.com (Renato
Ghica) writes:

|> Aren't the variables initialized in the order that they were declared, no
|> matter how you initializes then the constructor line?

The order in which the variables are initialized is defined, but this
will only imply an ordering of the evaluation of the initialization
expressions in the presence of sequence points.

For example: given the following class:

 struct C
 {
     int   a ;
     int   b ;
     C( int i ) : a( i ) , b( a ) {}
 } ;

It is guarenteed that 'a' will be initialized before 'b', but it is
not guarenteed that 'a' will be initialized before the expression used
to initialize 'b' is evaluated.  A perfectly legal implementation
would be: evaluate the expression initializing 'b' (in this case, the
not yet initialized 'a'), and push it on the stack.  Evaluate the
expression initializing 'a' (in this case, the parameter 'i') and push
it on the stack.  Pop to 'a'.  Pop to 'b'.  (In fact, I have been
informed by private email that there actually was a compiler that did
something like this.)
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung