Topic: trivial conversions


Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 15 Jan 1994 05:43:05 GMT
Raw View
In article <CJFM3p.6Ht@ses.com> jamshid@ses.com (Jamshid Afshar) writes:
>In article <rfgCJCpG6.DMv@netcom.com>,
>Ronald F. Guilmette <rfg@netcom.com> wrote:
>>>: >In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>>: >> Derived --> Derived const& --> Base const& --> Base
>>
>I don't see any problem with what John wrote.  The code in question is
>no different than:
>
> class Base {
> public:
>    Base(const Unrelated&);
> };
>
> class Unrelated {/*...*/};
> class U2 : public Unrelated {/*...*/};
>
> void foo(Base);
>
> main() {
>    U2 u;
>    foo(u);
> }
>
> U2 --> U2 const& --> Unrelated const& --> Base
>

>U2 => U2 const& involves trivial conversions.

 I think this is a case where the notation we're using
is horrendously awful :-)

 The variable "u" is an lvalue. The "conversion"

 U2-->U2 const&

physically means to take the address of that
lvalue: the address may be known or may require calculation.
Had there been an rvalue expression
of type U2 as an argument, the converion would first require
constructing a temporary object. Therefore, the first step
of a conversion sequence should be notated as the type
of the expression:

 {lvalue, U2} -->U2 const&
 {rvalue, U2} -->U2 const&

are distinct operations.   It may also look silly to write
a conversion sequence:

 T --> const T& --> T

but thats exactly how a copy constructor seems to operate :-)

>U2 const& => Unrelated
>const& is a standard conversion.  Unrelated const& => Base is a
>user-defined conversion .  Note that each matching sequence in 13.2
>(exact, promotions, standard, user-defined conversions, and ellipsis)
>includes any "lesser" or "easier" conversions.

 But is a copy constructor a user defined conversion?
Should there be a distinction between a user written copy
constructor and a compiler generated one?

 In what way is an upcast not a user defined conversion?
After all, deriving a class seems to be "user defined" to me.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 9 Jan 1994 07:14:29 GMT
Raw View
In article <1994Jan03.151134.22531@vedge.com> hendrik@vedge.com (Hendrik Boom) writes:
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>: In article <rfgCIw7Ew.MLB@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>: >In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>: >>
>: >> Derived --> Derived const& --> Base const& --> Base
>
>: >
>: >Very amusing John.
>: >
>: >(This is the first time I've ever seen anyone suggest that the right way to
>: >get from point A to point B... or from type A to type B, if you will... is
>: >to perform some kind of conversion, e.g. from object to reference, and then
>: >merely undo it later on!  As I say, very amusing.)
>:
>I don't see the humour either.  I'd really like to se an explanation
>why this back-and-forth conversion is illegal.

I never said it was "illegal".  It's just humorous because this seems like
such a round-about way of getting something simple done.  Why doesn't the
standard merely do something sensible... like for instance defining a
"trivial conversion" from a derived to a base?

Wouldn't it seem just a bit humorous if someone told you that the *right*
and "legal" way to convert a short to an int was via:

  short => long double => int

??

Surely things can be simpler!

--

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




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Mon, 27 Dec 1993 14:38:27 GMT
Raw View
In article <9335901.17196@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>ellis@summit.novell.com (-TEMP-+Ellis M.) writes:
>
>>:template<class T>
>>:void doA (T x, A & a) {
>>:    a.iam(x);
>>:}
>>:
>>:int main()
>>:{
>>:    B b;
>>:    doA ("in iam()", b);
>>:    return 0;
>>:}
>>:
>>:IBM's C++Set/2 compiles this without comment (and works). Clearly, it has
>>:matched the derived class reference with base class.
>>
>>As does cfront.
>
>Then both C++Set/2 and Cfront are buggy, because there is no instance
>of the doA() template for which doA() can be called with an exact match,
>as is required by ARM 14.4.

 1) The type system as described in the ARM is faulty.
    Some of these faults have been fixed by the committee.

    In particular, I think there is considerable confusion
    about conversions and types.

 2) In the light of (1), the trivial no conversions rule is
    unworkable. So most compilers have relaxed the restrictions.

 3) Although Base-->Derived is not a trivial conversion but
    a standard one, it is being considered that these
    be allowed for template argument matching.

 4) The actual problem above, however, should have nothing
    to do with this.  Because the parameter in question has
    no template formals in it. SO: if there is only one
    function template, either the generated template
    is callable or not: in the example its callable,
    so it should be legal.

    If overloading is allowed, the issue is much harder.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: ckincy@mcdga106 (student - SES Chuck Kincy)
Date: Tue, 28 Dec 1993 22:56:29 GMT
Raw View
In article <9335901.17196@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>I would disagree.  ARM 14.4 is quite clear that "not even trivial
>conversions (13.2) will be applied in this case", yet Cfront and
>C++Set/2 apply the standard conversion from B& to A& --- clearly
>a bug in these compilers, IMHO.

Although I agree that this issue is confusing, nonetheless you
have misunderstood that paragraph.

"A match on a template (step [2]) implies that a specific template
                        ^^^^^^^^^
function with arguments that exactly matches the types of the arguments
will be generated (S 14.5).  Not even trivial conversions (S 13.2)
will be applied in this case." (Ellis and Stroustrup, 346)
                ^^^^^^^^^^^^^

This simply means that there will be no match under criterion #2:

"[2]  Look for a function template from which a function that can
be called with an exact match can be generated; if found, call it."
(345-346)

The compiler then must proceed to criterion #3:

"[3]  Try ordinary overloading resolution (S 13.2) for the functions;
if a function is found, call it." (346)

And, just like Ms. Ellis suggested, on p. 318 you will find:

"[3]  Match with standard conversions...."

So, the IBM and AT&T compilers are WAD, and apparently the designers
of g++ and Borland C++ made the same oversight you did. :-)

cpk

[Page numbers refer to the May 1991 printing of the ARM.  Of course, X3J16
may have superceded this stuff by now...  :-)]
--
The opinion expressed in this post is that of the author, and is not
based upon the author's capacity as an employee of the USGS.
---
Chuck Kincy --- ckincy@mcdgs01.cr.usgs.gov --- +1 314 341-9391




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Wed, 29 Dec 1993 00:58:54 GMT
Raw View
ckincy@mcdga106 (student - SES Chuck Kincy) writes:

>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>>I would disagree.  ARM 14.4 is quite clear that "not even trivial
>>conversions (13.2) will be applied in this case", yet Cfront and
>>C++Set/2 apply the standard conversion from B& to A& --- clearly
>>a bug in these compilers, IMHO.
>
>Although I agree that this issue is confusing, nonetheless you
>have misunderstood that paragraph.

No, I stand by my original interpretation.

>"A match on a template (step [2]) implies that a specific template
>                        ^^^^^^^^^
>function with arguments that exactly matches the types of the arguments
>will be generated (S 14.5).  Not even trivial conversions (S 13.2)
>will be applied in this case." (Ellis and Stroustrup, 346)
>                ^^^^^^^^^^^^^
>
>This simply means that there will be no match under criterion #2:
>
>"[2]  Look for a function template from which a function that can
>be called with an exact match can be generated; if found, call it."
>(345-346)
>
>The compiler then must proceed to criterion #3:
>
>"[3]  Try ordinary overloading resolution (S 13.2) for the functions;
>if a function is found, call it." (346)

It seems quite clear to me that "the functions" refered to here are
only the *non-template* functions whose name matches the function
being called.  Ordinary overloading resolution is not even defined
for template functions, only for ordinary functions, and
the result can only be a function, not a function template.

>And, just like Ms. Ellis suggested, on p. 318 you will find:
>
>"[3]  Match with standard conversions...."

Your interpretation is clearly not what was intended by the ARM,
because it is contradicted by the example on page 346:

 template <class T> T max(T a, T b) { return a?b?a:b; }
 void f(int a, int b, char c, char d)
 {
  ...
  int m3 = max(a, c);    // error: cannot generate max(int, char)
 }

If standard conversions were allowed, then it would not be
an error, instead max(int, int) would be generated.
This example is exactly analagous to the original example, except
here the standard conversion is from char to int, whereas
in the original example it was from Derived& to Base&.
The example makes it quite explicit that this is an error.

--
Fergus Henderson        |   "People who brook no compromise in programming
                        |   languages should program in lambda calculus or
fjh@munta.cs.mu.OZ.AU   |   machine language, depending." --Andrew Koenig.




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Wed, 29 Dec 1993 09:05:26 GMT
Raw View
In article <CIp7C4.1yw@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>
> 3) Although Base-->Derived is not a trivial conversion but
>    a standard one...

Where is this defined to be a standard conversion, John?

--

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




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 30 Dec 1993 14:30:22 GMT
Raw View
In article <rfgCIsH92.HE2@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>In article <CIp7C4.1yw@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>
>> 3) Although Base-->Derived is not a trivial conversion but
>>    a standard one...
>
>Where is this defined to be a standard conversion, John?

 Oh, Woops!  First, I should have written

 Derived --> Base

 Next, you are correct its not in itself a standard conversion.
However, its is a conversion which can be COMPOSED of standard
conversions and "trivial" ones:

 Derived --> Derived const& --> Base const& --> Base

This crappy notation actually means you can call the Base
copy constructor with a Derived object as an argument.

The copy constructor is a trivial conversion, and the
binding of a Base reference to a Derived object
required a binding of a Derived reference (also a trivial
conversion) followed by a reference upcast (the standard
conversion).

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 31 Dec 1993 09:23:19 GMT
Raw View
In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>In article <rfgCIsH92.HE2@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>>In article <CIp7C4.1yw@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>>
>>> 3) Although Base-->Derived is not a trivial conversion but
>>>    a standard one...
>>
>>Where is this defined to be a standard conversion, John?
>
> Oh, Woops!  First, I should have written
>
> Derived --> Base
>
> Next, you are correct its not in itself a standard conversion.
>However, its is a conversion which can be COMPOSED of standard
>conversions and "trivial" ones:
>
> Derived --> Derived const& --> Base const& --> Base

Very amusing John.

(This is the first time I've ever seen anyone suggest that the right way to
get from point A to point B... or from type A to type B, if you will... is
to perform some kind of conversion, e.g. from object to reference, and then
merely undo it later on!  As I say, very amusing.)

--

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




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sat, 1 Jan 1994 09:31:46 GMT
Raw View
In article <rfgCIw7Ew.MLB@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>>>
>>>> 3) Although Base-->Derived is not a trivial conversion but
>>>>    a standard one...
>>>
>>>Where is this defined to be a standard conversion, John?
>>
>> Oh, Woops!  First, I should have written
>>
>> Derived --> Base
>>
>> Next, you are correct its not in itself a standard conversion.
>>However, its is a conversion which can be COMPOSED of standard
>>conversions and "trivial" ones:
>>
>> Derived --> Derived const& --> Base const& --> Base
>
>Very amusing John.
>
>(This is the first time I've ever seen anyone suggest that the right way to
>get from point A to point B... or from type A to type B, if you will... is
>to perform some kind of conversion, e.g. from object to reference, and then
>merely undo it later on!  As I say, very amusing.)

 Excuse me?  I miss the humor. There is no other possible
way to do it. This is what really must happen, physically.
Let me give an example:

 class Base { Base(const Base&); };
 class Derived : public Base {};
 Derived d;
 Base b = d;

Here is what is required to happen:

 1) the compiler allocates temporary store for a b
 2) the compiler binds the parameter of the Base
    copy constructor to d by passing in a pointer
    to it
 3) the constructor is invoked
 4) it initialises the temporary
 5) the temporary is copied by exactly the same
    process as (2)-(4) to the target b

Step 5 can be elided provided the copy constructor is accessible.

If the source is an rvalue, a d object must first be constructed.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: hilfingr@tully.CS.Berkeley.EDU (Paul N. Hilfinger)
Date: 2 Jan 1994 22:55:04 GMT
Raw View
In article <CIp7C4.1yw@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:

>  1) The type system as described in the ARM is faulty.
>     Some of these faults have been fixed by the committee.
>
>     In particular, I think there is considerable confusion
>     about conversions and types.

(This item is in an article concerning the "exact match" rule for
template instantiation.) Can anyone summarize briefly the specific
changes in this area that the committee has proposed or is currently
considering?  Thank you.

P. Hilfinger




Author: jamshid@ses.com (Jamshid Afshar)
Date: Mon, 10 Jan 1994 20:55:00 GMT
Raw View
In article <rfgCJCpG6.DMv@netcom.com>,
Ronald F. Guilmette <rfg@netcom.com> wrote:
>>: >In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>>: >> Derived --> Derived const& --> Base const& --> Base
>
>I never said it was "illegal".  It's just humorous because this seems like
>such a round-about way of getting something simple done.  Why doesn't the
>standard merely do something sensible... like for instance defining a
>"trivial conversion" from a derived to a base?

You mean Derived => Base should be a trivial conversion?  That would
make it a better match than Derived& => Base& or long => int, which
are standard conversions.

I don't see any problem with what John wrote.  The code in question is
no different than:

 class Base {
 public:
    Base(const Unrelated&);
 };

 class Unrelated {/*...*/};
 class U2 : public Unrelated {/*...*/};

 void foo(Base);

 main() {
    U2 u;
    foo(u);
 }

 U2 --> U2 const& --> Unrelated const& --> Base

>Wouldn't it seem just a bit humorous if someone told you that the *right*
>and "legal" way to convert a short to an int was via:
>                short => long double => int

It would definitely be wrong.  ARM 13.2: "no sequence of conversions
will be considred [...] can be shortened by deleting one or more
conversions [...]".

U2 => U2 const& involves trivial conversions.  U2 const& => Unrelated
const& is a standard conversion.  Unrelated const& => Base is a
user-defined conversion .  Note that each matching sequence in 13.2
(exact, promotions, standard, user-defined conversions, and ellipsis)
includes any "lesser" or "easier" conversions.

Jamshid Afshar
jamshid@ses.com




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Mon, 3 Jan 1994 11:36:15 GMT
Raw View
In article <2g7jc8$6r6@agate.berkeley.edu> hilfinger@CS.Berkeley.EDU writes:
>In article <CIp7C4.1yw@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>
>>  1) The type system as described in the ARM is faulty.
>>     Some of these faults have been fixed by the committee.
>>
>>     In particular, I think there is considerable confusion
>>     about conversions and types.
>
>(This item is in an article concerning the "exact match" rule for
>template instantiation.) Can anyone summarize briefly the specific
>changes in this area that the committee has proposed or is currently
>considering?  Thank you.

 The following changes have been made:

 void f(const int);
 void f(int);

denote the same function.

 const T g();
 T h();
 g().mem(); // calls const member
 h().mem(); // calls non-const member

There are no longer expressions with type T&.

 T x;
 T& y = x;
 x++;
 y++;

The expression types of x and y as used here are the same:
lvalue of type int.

Functions which cant be called (other than for reasons of
access protection) are excluded from overload resolution.

The rules for function template matching will be relaxed.
Some trivial conversions will be allowed, and possibly
upcasts.

In general, overload resolution and argument matching
is yet to be specified precisely. For example,
use of operator conversions is not well determined,
and the interaction of built-in operators with user
defined ones is currently undefined.

The type system is probably the hardest part of C++
to get right.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: hendrik@vedge.com (Hendrik Boom)
Date: Mon, 03 Jan 1994 15:11:34 GMT
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:
: In article <rfgCIw7Ew.MLB@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
: >In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
: >>>>
: >>>> 3) Although Base-->Derived is not a trivial conversion but
: >>>>    a standard one...
: >>>
: >>>Where is this defined to be a standard conversion, John?
: >>
: >> Oh, Woops!  First, I should have written
: >>
: >> Derived --> Base
: >>
: >> Next, you are correct its not in itself a standard conversion.
: >>However, its is a conversion which can be COMPOSED of standard
: >>conversions and "trivial" ones:
: >>
: >> Derived --> Derived const& --> Base const& --> Base

     ^^^^^^^^^^^^^^^^^^^

Presumably this conversion is done via a copy constructor.,
so it's not the Base that is the argument to the copy constructor;
its the reference to constant Base.

: >
: >Very amusing John.
: >
: >(This is the first time I've ever seen anyone suggest that the right way to
: >get from point A to point B... or from type A to type B, if you will... is
: >to perform some kind of conversion, e.g. from object to reference, and then
: >merely undo it later on!  As I say, very amusing.)
:
:  Excuse me?  I miss the humor. There is no other possible
: way to do it. This is what really must happen, physically.
: Let me give an example:

I don't see the humour either.  I'd really like to se an explanation
why this back-and-forth conversion is illegal. It has given me
headaches for about a year now.  I'd love the joke to be on me --
all those wasted headaches :-)
--
-------------------------------------------------------
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: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 5 Jan 1994 04:21:04 GMT
Raw View
In article <1994Jan03.151134.22531@vedge.com> hendrik@vedge.com (Hendrik Boom) writes:
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>: In article <rfgCIw7Ew.MLB@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>: >In article <CIuqyn.JJG@ucc.su.OZ.AU> maxtal@physics.su.OZ.AU (John Max Skaller) writes:
>: >>>>
>: >>>> 3) Although Base-->Derived is not a trivial conversion but
>: >>>>    a standard one...
>: >>>
>: >>>Where is this defined to be a standard conversion, John?
>: >>
>: >> Oh, Woops!  First, I should have written
>: >>
>: >> Derived --> Base
>: >>
>: >> Next, you are correct its not in itself a standard conversion.
>: >>However, its is a conversion which can be COMPOSED of standard
>: >>conversions and "trivial" ones:
>: >>
>: >> Derived --> Derived const& --> Base const& --> Base
>
>     ^^^^^^^^^^^^^^^^^^^
>
>Presumably this conversion is done via a copy constructor.,
>so it's not the Base that is the argument to the copy constructor;
>its the reference to constant Base.

 No, this is the confusion the committee has to
deal with. A reference cannot ever be an argument,
no expressions have reference type. This has been
decided. :-)

 The argument is a Derived object. The parameter
is a Base const&. In practice the binding occurs by

 a) taking the address of the derived object;
    this is equivalent to the "conversion"
  Derived --> Derived const&

 b) upcast the pointer, this is the "conversion"
  Derived const& --> Base const&

 c) Pass the pointer value to the copy constructor,

 d) the copy constructor returns a Base so thats the
    "conversion"
  Base const& --> Base

>I don't see the humour either.  I'd really like to se an explanation
>why this back-and-forth conversion is illegal. It has given me
>headaches for about a year now.  I'd love the joke to be on me --
>all those wasted headaches :-)

 Yes. Its hairy stuff, IMHO because the ARM is chock ablock
full of category errors and overloaded meanings of things that
are subtly different and nowhere is this more apparant that
when dealing with the so called "type system" and issues like
initialisation, conversions, overloading, object types, declarative
types, expresssion types etc etc.

 Forming a consistent type system is HARD because the
committee has to take into account all the existing code
and compilers that misinterpret the unspecified system
in ways of their own choosing. Its made even harder by
having to cope with C compatibility, and attempts to
retain compatibility with existing incoherent descriptions.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Fri, 24 Dec 1993 14:33:21 GMT
Raw View
ellis@summit.novell.com (-TEMP-+Ellis M.) writes:

>davidn@csource.oz.au (david nugent) writes:
>:In particular, it seems unclear to me whether the conversion of a pointer or
>:reference to an object of a given class to a pointer or reference to an object
>:of one of its base classes requires a 'trivial conversion' or not. Given that
>:inheritence implements an "is-a-kind-of" relationship between the derived and
>:base class, that indicates to me that there is no conversion or any sort
>:required - it already IS the correct type (the actual mechanics of conversion
>:between a class and a virtual base being irrelevent at the language level).
>
>The relationship of these conversions to function matching is discussed
>on p. 318.

In particular, a conversion _is_ required to convert from a Derived* to
a Base*, and furthermore this conversion is not a trivial conversion,
it's a standard conversion, and so it is considered in step 3 of the
argument matching rules.

>:class A { ... };
>:class B : public A { ... };
>:
>:template<class T>
>:void doA (T x, A & a) {
>:    a.iam(x);
>:}
>:
>:int main()
>:{
>:    B b;
>:    doA ("in iam()", b);
>:    return 0;
>:}
>:
>:IBM's C++Set/2 compiles this without comment (and works). Clearly, it has
>:matched the derived class reference with base class.
>
>As does cfront.

Then both C++Set/2 and Cfront are buggy, because there is no instance
of the doA() template for which doA() can be called with an exact match,
as is required by ARM 14.4.

>:Borland C++ for OS/2 complains:
>:
>:virt.cpp:
>:Error virt.cpp 32: Could not find a match for 'doA(char *,B)' in function
>:main()
>:*** 1 errors in Compile ***
>:
>:Similarly, gcc 2.4.5:
>:
>:gcc   -O2  -Wall       -o virt virt.cpp
>:virt.cpp: In function `int  main ()':
>:virt.cpp:32: type unification failed for function template
>:
>:Am I correct in assuming that the latter two compilers are 'broken'?
>
>I would say so.

I would disagree.  ARM 14.4 is quite clear that "not even trivial
conversions (13.2) will be applied in this case", yet Cfront and
C++Set/2 apply the standard conversion from B& to A& --- clearly
a bug in these compilers, IMHO.

--
Fergus Henderson        |   "People who brook no compromise in programming
                        |   languages should program in lambda calculus or
fjh@munta.cs.mu.OZ.AU   |   machine language, depending." --Andrew Koenig.