Re: Incorrect implementation of dynamic_cast<>

From: A Schneider at XCC (angelos@xcc.de)
Date: Wed Sep 01 1999 - 03:48:54 MEST


Hi,

your question was:

>problem was.  Calling func with an argument which is a Base * should 
>always call func(Base *).  Calling func with an argument of Derived * 
>should always call func(Derived *). In both of those cases CINT behaves 
>correctly.  Calling func with an argument of Derived2 *, it seems that 
>the proper behavior would be to call func(Derived *), not func(Base *); 
>and that is in fact what egcs does.
>I don't know what the ANSI C++ standard says about this.  If anyone can 
>point me to that document somewhere, I'll be happy to look it up...

Rest deleted but I would support "George Heintzelman".

Well,

I dont have the ARM at hand yet.

Simplyfied:
ANSI asks the compiler to call the function, where the least
number of argument conversions/propagations/casts have to be done.

Example:
So if you have a hierarchy: Leave --|> Derived --|> Base
Functions func(Base& b), func(Derived& d)
and an Object Leave l.

Expected:
The call func(l) should be compiled/dispatched to func((Derived&)l),
that means the function func(Derived& d) should be called.

Note:
to call func(Base& b) here there are two casts needed:
func((base&)(Derived&)l);

In fact there is a further problem.

Function hiding. But this "braindead" idea of some C++ GURU, is
normaly flagged by the compiler and leads to the fact that nothing is 
called, everything which is intuitive is an error :-)

Angelo

Oh, I read a bit further in you previous eMail:

>From a strict reading of Stroustrup (3rd ed, pp. 149 - 150), it would 
>seem that the first call should actually be regarded as ambiguous, but 
>neither egcs nor root reported either an error or warning, and egcs's 
>behavior is much more intuitive. I couldn't find a clearer statement of 
>the official standard anywhere, unfortunately.

No: it is not ambigous!

You have some functions func(ARG a), func(BLOP b), func(CAP c) ...

and a call func(q?).

The compiler is supposed to look at each function func(...) he nows
about (well, template functions complicate it a bit but are well
incorporated). If it can find one function where the argument 
type matches the type of q?, that one will be called, trivial ok.

If the compiler finds one function where the argument type matches
the formal parameter type, that function will be called.

If the compiler finds one function where the argument type can be
casted to the formal parameter type, that function will be called.

If the compiler finds a function where the formal parameter type 
has a constructor which acceptes an argument q?, that function will be 
called, and an temporary (anonymous) object of that type will be 
created.

There are further propagations/casts ...

Well if the compiler encounters several posibilities of that above,
where the number of conversions are the same, 
THEN the call is ambigous.

Oh, I forgott: for one argument there is only one 
conversion/cast/propagation/constructor-call allowed.

If a function has several arguments, this is true for each one.
If two functions need different conversions for arguments at matching
positions, the call is ambigous.

e.g.
func(double d, int i);
func(int i, int j);

call:
func('a', 1.3); // this should be ambigous
func((int)'a', 1.3); // this makes it clearer, the compiler needs
		     // to cast both args, regardless which function to 
		     // call

Hope that helps,
	Best Regards,
		Angelo Schneider



---------------------------------------------------------------------
Angelo Schneider           OOAD/UML           Angelo.Schneider@xcc.de
Putlitzstr. 24         Patterns/FrameWorks       Fon: +49 721 9812465
76137 Karlsruhe             C++/JAVA             Fax: +49 721 9812467



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:39 MET