Topic: Q: cast operator
Author: clerc@gla.ecoledoc.ibp.fr
Date: 25 Feb 1995 15:44:11 GMT Raw View
what does the ARM/WP say about the way the
program below is supposed to behave ?
IBM says that xlC is the only one to get it 'right'.
thanks to all
#include <iostream.h>
class A {};
class B {
public:
operator A const&() const { cout<<"ok"; return a_; }
private:
A a_;
};
int main() {
B b;
A a;
cout<<"1: "; a=(A&)b; cout<<endl;
cout<<"2: "; a=(A const&)b; cout<<endl;
cout<<"3: "; a=b; cout<<endl;
return 1;
}
#if 0
IBM xlC 2.1(.2?)
----------------
% xlC t.C
% a.out
1:
2:
3: ok
Sun CC 4.0.1
------------
% CC t.C
"t.C", line 24: Warning (Anachronism): Cannot cast from B to A.
"t.C", line 24: Note: Type "CC -migration" for more on anachronisms.
"t.C", line 24: Warning (Anachronism): Cannot cast from B to A.
2 Warning(s) detected.
% a.out
1:
2: ok
Bus error (core dumped)
HP C++3.5
---------
% CC t.C
% a.out
1:
2: ok
3: ok
Watcom C++ v10.0
----------------
C:\tmp>wcl386 /zq t.cpp
C:\tmp>t.exe
1:
2: ok
3: ok
#endif
Keywords:
Author: jason@cygnus.com (Jason Merrill)
Date: 28 Feb 1995 00:28:45 GMT Raw View
>>>>> clerc <clerc@gla.ecoledoc.ibp.fr> writes:
> what does the ARM/WP say about the way the
> program below is supposed to behave ?
> IBM says that xlC is the only one to get it 'right'.
...
> operator A const&() const { cout<<"ok"; return a_; }
...
> cout<<"1: "; a=(A&)b; cout<<endl;
> cout<<"2: "; a=(A const&)b; cout<<endl;
> cout<<"3: "; a=b; cout<<endl;
...
The pertinent text in the WP is:
5.2.8 Static cast [expr.static.cast]
2 Any implicit conversion (including standard conversions and/or user-
defined conversions; see _conv_ and _over.best.ics_) can be performed
explicitly using static_cast. More precisely, if T t(v); is a well-
formed declaration, for some invented temporary variable t, then the
result of static_cast<T>(v) is defined to be the temporary t, and is
an lvalue if T is a reference type, and an rvalue otherwise. The
expression v shall be an lvalue if the equivalent declaration requires
an lvalue for v.
5.2.9 Reinterpret cast [expr.reinterpret.cast]
12An lvalue expression of type T1 can be cast to the type reference to
T2 if an expression of type pointer to T1 can be explicitly converted
to the type pointer to T2 using a reinterpret_cast. That is, a refer-
ence cast reinterpret_cast<T&>x has the same effect as the conversion
*reinterpret_cast<T*>&x with the built-in & and * operators. The
result is an lvalue that refers to the same object as the source
lvalue, but with a different type. No temporary is created, no copy
is made, and constructors (_class.ctor_) or conversion functions
(_class.conv_) are not called.
5.4 Explicit type conversion (cast notation) [expr.cast]
4 The conversions performed by static_cast (_expr.static.cast_), rein-
terpret_cast (_expr.reinterpret.cast_), const_cast
(_expr.const.cast_), or any sequence thereof, can be performed using
the cast notation of explicit type conversion. The same semantic
restrictions and behaviors apply. If a given conversion can be per-
formed using either static_cast or reinterpret_cast, the static_cast
interpretation is used.
The conversion '(A const&)b' can be interpreted as
static_cast <A const&> (b) or
reinterpret_cast <A const&> (b);
I think it is obvious from the [expr.cast] text that the former
interpretation is preferred, so xlC gets it 'wrong'.
The conversion '(A&)b' can be interpreted as
const_cast <A&> (static_cast <A const&> (b)) or
reinterpret_cast <A&> (b).
I don't think the WP is clear enough on this point to say conclusively what
the 'right' answer is. Perhaps it should be considered ambiguous.
However, I believe that all existing compilers choose the latter option
here.
Jason