Topic: portability question.


Author: hendrik@vedge.com (Hendrik Boom)
Date: Thu, 23 Sep 1993 21:09:32 GMT
Raw View
kanze@us-es.sel.de (James Kanze) writes:
:
: Note that if I interpret the ARM literally, gcc and Borland are right
: and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
: says: "A copy constructor for a class X ... is one that can be called
: with a single argument of type X."  Since the constructor 'B::B( A& a,
: int z = -1 )' can be called with a single argument of type B, it is a
: copy constructor (by this definition).  And since you have provided a
: copy constructor, the compiler should not provide another.
:
: I personally suspect that this was not the intent of the ARM.

It may not be the intent, but in that case the example in the
fine print on section 264, which says that X::X(X&, int=0)
is a copy constructor, must be there by mistake. :=)






--
-------------------------------------------------------
Try one or more of the following addresses to reply.
at work: hendrik@vedge.com,  iros1!vedge!hendrik
at home: uunet!ozrout!topoi!hendrik




Author: kanze@us-es.sel.de (James Kanze)
Date: 27 Sep 93 21:09:01
Raw View
In article <1993Sep23.210932.15834@vedge.com> hendrik@vedge.com
(Hendrik Boom) writes:

|> kanze@us-es.sel.de (James Kanze) writes:
|> :
|> : Note that if I interpret the ARM literally, gcc and Borland are right
|> : and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
|> : says: "A copy constructor for a class X ... is one that can be called
|> : with a single argument of type X."  Since the constructor 'B::B( A& a,
|> : int z = -1 )' can be called with a single argument of type B, it is a
|> : copy constructor (by this definition).  And since you have provided a
|> : copy constructor, the compiler should not provide another.
|> :
|> : I personally suspect that this was not the intent of the ARM.

|> It may not be the intent, but in that case the example in the
|> fine print on section 264, which says that X::X(X&, int=0)
|> is a copy constructor, must be there by mistake. :=)

There is no doubt that 'X::X( X& , int = 0 )' is a copy constructor
for X.  The question was: is it a copy constructor for a class derived
from X.

The actual wording in the ARM says that it would be, but at least some
compilers (cfront) say that it is not.  In addition, Ms. Ellis has
pointed out that the current working draft of the standard has changed
the wording to say that it is not.  As Ms. Ellis is defending the
position that it is not a copy constructor, and she is co-author of
the ARM, I take this as a very strong indication that my suspicion is
correct, ie: that it was just an unfortunate choice of wording that
says it was a copy constructor in the ARM.
--
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: kanze@us-es.sel.de (James Kanze)
Date: 17 Sep 93 12:32:31
Raw View
In article <279rhdINN3nf@marble.usl.com> ellis@usl.com (-TEMP-+Ellis
M.) writes:

|> A recent draft of the ANSI C++ standard revises 12.1, as follows:

|>  A copy constructor for a class X is a constructor whose first parameter
|>  is of type X& or const X& and whose other parameters, if any, all have
|>  defaults, so that it can be called with a single argument of type X.
|>  For example, X::X(const X&) and X::X(X&, int=0) are copy constructors.

|> Centerline (and cfront) implement the intended behavior.

This brings up an interesting question.

Most people don't have a copy of the draft.  And even for those that
do, I would suggest sticking to the ARM as a reference until the draft
is at least made public.  (I'm talking about users here, not compiler
manufacturers.)  As for places where the ARM is ambiguous, or where
there is reason to suspect that the intent is not exactly what is
written, my suggestion is simply to avoid them.  These are things that
are very important to a compiler writer, but really don't (or
shouldn't) be of that much concern to those of us who just write
programs.

Thus, I suggested to the original poster to provide his own copy
constructor; he is safe no matter how the compiler implementer
interprets the ARM, and no matter what decision the standards
committee finally makes.  Pointing out that cfront is correct
(according to the standards committee) and that compiler X is wrong
really doesn't help me if I have to compile with compiler X.  And of
course, as long as the standard isn't a standard, the standards
committee could vote in the next meeting to make cfront wrong and X
right.  (Although I'd be willing to bet that this won't happen on this
issue.)

This is not meant to criticize Ms. Ellis for bringing the point up.
While I don't think we should take advantage of it yet, it is nice to
know what is happening.  And since she seems to accept the
interpretation above, I guess we can assume that this was really the
intent in the ARM.  Although we always tend to say, "What did Bjarne
mean here?" we shouldn't forget that Ms. Ellis is in fact co-author of
the ARM.
--
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: kanze@us-es.sel.de (James Kanze)
Date: 15 Sep 93 12:18:53
Raw View
In article <CDBLrw.95u@cerc.wvu.edu> almasi@cerc.wvu.edu (George
Almasi) writes:

|> A question to C++ hackers. Please compile this on

|>  1) Objectcenter /AT&T C++ ver 1.1
|>  2) gcc ver 2.1
|>  3) Borland C++ ver 3.1

|> and see what results you get:

|> almasi> CC porttest.cxx
|> CC  porttest.cxx:
|> cc  -L/usr/CenterLine/bin/../c++_1.1.0-r1.0/sun4-40/lib   porttest.c -lC
|> almasi> a.out
|> <5,7>

|> almasi> g++ porttest.cxx
|> almasi> a.out
|> <5,-1>

|> bcc porttest.cxx
|> porttest
|> <5,-1>

|>  Can anybody tell how to make bcc and gcc copy CC's behavior? in other
|> words, how to make them prefer the compiler-generated constructor of B to
|> B(A&, int) ?

Try defining the copy constructor yourself.  This works for g++
version 2.2.2.

Note that if I interpret the ARM literally, gcc and Borland are right
and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
says: "A copy constructor for a class X ... is one that can be called
with a single argument of type X."  Since the constructor 'B::B( A& a,
int z = -1 )' can be called with a single argument of type B, it is a
copy constructor (by this definition).  And since you have provided a
copy constructor, the compiler should not provide another.

I personally suspect that this was not the intent of the ARM.

Independantly of which compiler is right, why lean on a shakey
interpretation, which may be changed by the standards committee.  When
in doubt, provide your own copy constructor; that way, you are sure to
get the behavior you want.

BTW, as suggested in a recent posting by Bjarne, I have cross-posted
to comp.std.c++ and set the follow-ups to there too.  Any responses
are likely to be discussions of the strict interpretation of the ARM
(language lawering), and are probably more appropriate to that forum
than here.

[Initial program...]
-----------------------
#include <iostream.h>

class A
{
protected:
   int _v;
   int _z;
public:
   int v () { return _v; }
   int z () { return _z; }
   A(A& a) { _v = a.v(); _z = a.z(); }
   A(int x, int z) { _v = x; _z = z;}
};

class B: public A
{
public:
  B(A& a, int z = -1): A(a){ _z = z;}
};

main ()
{
  A a(5, 6);            // a = <5, 6>
  B b(a, 7);            // b = <5, 7>
  B c(b);               // c = <5, 7> or c = <5, -1>
  cout << "<" << c.v() << "," << c.z() << ">" << endl;
}

------------------------
--
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: osinski@panini.cs.nyu.edu (Ed Osinski)
Date: 16 Sep 1993 00:58:50 GMT
Raw View
In article <KANZE.93Sep15121853@slsvhdt.us-es.sel.de>, kanze@us-es.sel.de (James Kanze) writes:
|> In article <CDBLrw.95u@cerc.wvu.edu> almasi@cerc.wvu.edu (George
|> Almasi) writes:
|>
|> |> A question to C++ hackers. Please compile this on
|>
|> |>  1) Objectcenter /AT&T C++ ver 1.1
|> |>  2) gcc ver 2.1
|> |>  3) Borland C++ ver 3.1
|>
|> |> and see what results you get:
|>
|> |> almasi> CC porttest.cxx
|> |> CC  porttest.cxx:
|> |> cc  -L/usr/CenterLine/bin/../c++_1.1.0-r1.0/sun4-40/lib   porttest.c -lC
|> |> almasi> a.out
|> |> <5,7>
|>
|> |> almasi> g++ porttest.cxx
|> |> almasi> a.out
|> |> <5,-1>
|>
|> |> bcc porttest.cxx
|> |> porttest
|> |> <5,-1>
|>
|> |>  Can anybody tell how to make bcc and gcc copy CC's behavior? in other
|> |> words, how to make them prefer the compiler-generated constructor of B to
|> |> B(A&, int) ?
|>
|> Try defining the copy constructor yourself.  This works for g++
|> version 2.2.2.
|>
|> Note that if I interpret the ARM literally, gcc and Borland are right
|> and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
|> says: "A copy constructor for a class X ... is one that can be called
|> with a single argument of type X."  Since the constructor 'B::B( A& a,
|> int z = -1 )' can be called with a single argument of type B, it is a
|> copy constructor (by this definition).  And since you have provided a
|> copy constructor, the compiler should not provide another.
|>
|> I personally suspect that this was not the intent of the ARM.

That's an odd thing to say, especially considering the sentence in the ARM
immediately following the one you quoted:

 "For example, X::X(const X&) and X::X(X&,int=0) are copy constructors."

This is exactly the case in the code above, modulo different names and default
value.

  [ stuff deleted ]

|> --
|> 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

--
---------------------------------------------------------------------
 Ed Osinski                  |
 Computer Science Department | "I hope life isn't a big joke,
 New York University         |  because I don't get it."
 E-mail:  osinski@cs.nyu.edu |                           Jack Handey
---------------------------------------------------------------------




Author: kanze@us-es.sel.de (James Kanze)
Date: 16 Sep 93 11:21:55
Raw View
In article <278doa$lug@slinky.cs.nyu.edu> osinski@panini.cs.nyu.edu
(Ed Osinski) writes:

|> |> Note that if I interpret the ARM literally, gcc and Borland are right
|> |> and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
|> |> says: "A copy constructor for a class X ... is one that can be called
|> |> with a single argument of type X."  Since the constructor 'B::B( A& a,
|> |> int z = -1 )' can be called with a single argument of type B, it is a
|> |> copy constructor (by this definition).  And since you have provided a
|> |> copy constructor, the compiler should not provide another.

|> |> I personally suspect that this was not the intent of the ARM.

|> That's an odd thing to say, especially considering the sentence in the ARM
|> immediately following the one you quoted:

|>  "For example, X::X(const X&) and X::X(X&,int=0) are copy constructors."

|> This is exactly the case in the code above, modulo different names and default
|> value.

I hesitated because of this, too.  But both of the examples have the
class being copied as the first parameter; the original example in
this thread had a base class.

I suspect - but I am admittedly just guessing - that the intent was
that the first (non-default) parameter be a reference to the class
itself, and not just one of its (eventually very remote) base classes.
I will admit that I base my guess on very flimsy evidence, but all of
the descriptions of copy constructor I have seen (including those of
Bjarne himself) have talked about coping two objects of the *same*
type.

Of course, it says what it says, and were I implementing a compiler
today, I think I would implement what it says, and not what I think
Bjarne really meant to say.
--
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: ellis@usl.com (-TEMP-+Ellis M.)
Date: 16 Sep 1993 10:00:13 -0400
Raw View
In article <KANZE.93Sep15121853@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
:In article <CDBLrw.95u@cerc.wvu.edu> almasi@cerc.wvu.edu (George
:Almasi) writes:
:
:|> A question to C++ hackers. Please compile this on
:
:|>  1) Objectcenter /AT&T C++ ver 1.1
:|>  2) gcc ver 2.1
:|>  3) Borland C++ ver 3.1
:
:|> and see what results you get:
:
:|> almasi> CC porttest.cxx
:|> CC  porttest.cxx:
:|> cc  -L/usr/CenterLine/bin/../c++_1.1.0-r1.0/sun4-40/lib   porttest.c -lC
:|> almasi> a.out
:|> <5,7>
:
:|> almasi> g++ porttest.cxx
:|> almasi> a.out
:|> <5,-1>
:
:|> bcc porttest.cxx
:|> porttest
:|> <5,-1>
:
:|>  Can anybody tell how to make bcc and gcc copy CC's behavior? in other
:|> words, how to make them prefer the compiler-generated constructor of B to
:|> B(A&, int) ?
:
:Try defining the copy constructor yourself.  This works for g++
:version 2.2.2.
:
:Note that if I interpret the ARM literally, gcc and Borland are right
:and cfront (ObjectCenter) is wrong.  In section 12.1 of the ARM, it
:says: "A copy constructor for a class X ... is one that can be called
:with a single argument of type X."  Since the constructor 'B::B( A& a,
:int z = -1 )' can be called with a single argument of type B, it is a
:copy constructor (by this definition).  And since you have provided a
:copy constructor, the compiler should not provide another.
:
:I personally suspect that this was not the intent of the ARM.
:
:Independantly of which compiler is right, why lean on a shakey
:interpretation, which may be changed by the standards committee.  When
:in doubt, provide your own copy constructor; that way, you are sure to
:get the behavior you want.
:
:BTW, as suggested in a recent posting by Bjarne, I have cross-posted
:to comp.std.c++ and set the follow-ups to there too.  Any responses
:are likely to be discussions of the strict interpretation of the ARM
:(language lawering), and are probably more appropriate to that forum
:than here.
:
:[Initial program...]
:-----------------------
:#include <iostream.h>
:
:class A
:{
:protected:
:   int _v;
:   int _z;
:public:
:   int v () { return _v; }
:   int z () { return _z; }
:   A(A& a) { _v = a.v(); _z = a.z(); }
:   A(int x, int z) { _v = x; _z = z;}
:};
:
:class B: public A
:{
:public:
:  B(A& a, int z = -1): A(a){ _z = z;}
:};
:
:main ()
:{
:  A a(5, 6);            // a = <5, 6>
:  B b(a, 7);            // b = <5, 7>
:  B c(b);               // c = <5, 7> or c = <5, -1>
:  cout << "<" << c.v() << "," << c.z() << ">" << endl;
:}
:
:------------------------
:James Kanze                             email: kanze@us-es.sel.de


A recent draft of the ANSI C++ standard revises 12.1, as follows:

 A copy constructor for a class X is a constructor whose first parameter
 is of type X& or const X& and whose other parameters, if any, all have
 defaults, so that it can be called with a single argument of type X.
 For example, X::X(const X&) and X::X(X&, int=0) are copy constructors.

Centerline (and cfront) implement the intended behavior.

M. A. Ellis