egcs-1.0.1 confused by explicit cast

Jason Merrill jason@cygnus.com
Thu Feb 5 18:28:00 GMT 1998


>>>>> Adam P Jenkins <ajenkins@cs.umass.edu> writes:

>> 5.2.9  Static cast                                  [expr.static.cast]
>> 
>> 2 An expression e can be explicitly  converted  to  a  type  T  using  a
>> static_cast  of the form static_cast(e) if the declaration T t(e);"
>> is well-formed, for some invented temporary variable  t  (_dcl.init_).
>> The  effect  of  such an explicit conversion is the same as performing
>> the declaration and initialization and then using the temporary  vari-
>> able as the result of the conversion.
>> 
>> Since the above declaration is a direct-initialization, and so the
>> candidates are the constructors of T, the same is true of a cast.  The cast
>> notation does not have different semantics.

> The only way the above clause could be interpreted as saying that "an
> explicit cast is treated as an explicit constructor call, not a
> conversion", even when the class has a user-defined conversion
> function, is if you are not aware that C++ has user-defined conversion
> functions.  If they don't get called even when an explicit cast is
> used, then what are they even in the language for?

They get called for implicit conversions, to satisfy the argument types to
constructors.  Are you suggesting that the temporary variable t is not
initialized by a constructor if T is a class type?  That's nonsense.

> class A {
> public:
>   operator int() { return 1; }
> };

> int main()
> {
>   A a;
>   int i = (int)a; // calls A::operator int(), not int::int(A&)
>   i = int(a);     // again, calls A::operator int()
>   i = a;          // and yet again...
>   return i;
> }

> This program is legal, and in fact compiles with egcs, because the
> conversion operator calls the conversion function, not a constructor
> of int.

Yes, because int is not a class type.  Here's another quote for you:

  13.3  Overload resolution                                 [over.match]

2 Overload  resolution  selects  the  function to call in seven distinct
  contexts within the language:

...
  --invocation  of  a constructor for direct-initialization (_dcl.init_)
    of a class object (_over.match.ctor_);

  --invocation of  a  user-defined  conversion  for  copy-initialization
    (_dcl.init_) of a class object (_over.match.copy_);

  --invocation  of a conversion function for initialization of an object
    of  a   nonclass   type   from   an   expression   of   class   type
    (_over.match.conv_); and

  --invocation  of  a conversion function for conversion to an lvalue to
    which  a  reference  (_dcl.init.ref_)   will   be   directly   bound
    (_over.match.ref_).

If you are casting to a class type, you use the constructor, as described
in over.match.ctor.  If a non-class type, you look for conversion
functions, as described in over.match.conv.

I won't respond to any further mail on this subject.  Trust me, I know what
I'm talking about.

Jason



More information about the Gcc-bugs mailing list