Topic: refcast ambiguity "((<typename> &) <expression>)


Author: jacob@objy.com (Jacob Butcher)
Date: Wed, 6 Oct 93 21:13:57 GMT
Raw View
With the following declarations:

  class to {
  };

  class from {
    public:
      int before;
      to aTo;

      operator
   to &()
       { return (this->aTo); }
  };

most compilers (for example, Sun's) compile these two statements identically:

  to &t = f;
  to &t = ((to &) (f));

However, IBM's xlC compiler for AIX on an IBM RT compiles them differently.
Specifically, that compiler invokes the user-defined conversion for the
first statement, but does *not* invoke that conversion for the second
statement.  When I reported this discrepancy to IBM, they pointed out that
the ARM, section 5.4, page 69, line 9 states that

 ``Constructors or conversion functions are not called as
 the result of a cast to a reference.''

which certainly supports their implementation.  However, their implementation
violates what I (perhaps naively) assume to be an invariant of the language,
which is that if it is legal to assign an expression of type F to a variable
of type T, then it is legal to *cast* an expression of type F to type T, and
the operations are identical.  (Actually, C++ is sufficiently complex that
I'm not *too* attached to that invariant in general... I just want to say
that as a user I am *very* suprised by this discrepancy, and I think it is
wrong.)  So, is IBM mis-interpreting the ARM, or is theirs indeed a legitemate
interpretation of a deliberate ambiguity in the language?

    Jacob Butcher
    jacob@objy.com




Author: pkt@lpi.liant.com (Scott Turner)
Date: Tue, 12 Oct 1993 16:28:54 GMT
Raw View
In article <1993Oct6.211357.7098@objy.com>, jacob@objy.com (Jacob Butcher) writes:

> most compilers (for example, Sun's) compile these two statements identically:
>
>   to &t = f;
>   to &t = ((to &) (f));
>
> However, IBM's xlC compiler for AIX on an IBM RT compiles them differently.

> However, their implementation
> violates what I (perhaps naively) assume to be an invariant of the language,
> which is that if it is legal to assign an expression of type F to a variable
> of type T, then it is legal to *cast* an expression of type F to type T, and
> the operations are identical.

That would be nice as an invariant, but C++ explicit casts break it.
For example,

 void foo(float x) {
  const int &r1 = x;         // Refer to a temporary int object.
  const int &r2 = (const int &)x;  // Reinterpret the bits of x.
 }
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com




Author: pkt@lpi.liant.com (Scott Turner)
Date: Tue, 12 Oct 1993 13:48:38 GMT
Raw View
In article <1993Oct6.211357.7098@objy.com>, jacob@objy.com (Jacob Butcher) writes:

> most compilers (for example, Sun's) compile these two statements identically:
>
>   to &t = f;
>   to &t = ((to &) (f));
>
> However, IBM's xlC compiler for AIX on an IBM RT compiles them differently.

> However, their implementation
> violates what I (perhaps naively) assume to be an invariant of the language,
> which is that if it is legal to assign an expression of type F to a variable
> of type T, then it is legal to *cast* an expression of type F to type T, and
> the operations are identical.

That would be a nice invariant to have, but C++ reference casts break it.
For example,
 void foo(float x) {
  const int &r1 = x;  // refer to a temporary int object
  const int &r2 = (const int &)x;  // reinterpret the bits of x
 }
--
Prescott K. Turner, Jr.
Liant Software Corp. (developers of LPI languages)
959 Concord St., Framingham, MA 01701 USA    (508) 872-8700
UUCP: uunet!lpi!pkt                          Internet: pkt@lpi.liant.com