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