robertk@lotatg.lotus.com (Robert Krajewski) (04/25/91)
I have a function that returns a pointer to a parent class -- it looks
at its arguments, and then makes a new object (with new) either of
child class A, or B, depending on the arguments to this function. The
decision is made in a conditional expression, and the result is
returned:
Parent * MakeIt(...)
{
...
return ( <cond> ? new A(...) : new B(...) );
}
g++ warns that the two expressions are of different types, and so does
MPW C++.
However, it seems to me that I shouldn't get a warning. (MPW C++
actually considers this an error.) Return value conversion ought to be
following the same rules as conversion of class pointer types. This
code should not produce warnings:
F(Parent * thing);
F(new A(...));
F(new B(...));
... and I would argue that something analogous is happening in the
conditional expression example above.
Is there anything in the ARM to contradict what I'm saying ? If so, do
I have a reasonable complaint that should be addressed in the
standards effort ?
mittle@blinn.watson.ibm.com (Josh Mittleman) (04/26/91)
In article <ROBERTK.91Apr25110048@lotatg.lotus.com>, robertk@lotatg.lotus.com (Robert Krajewski) writes: > I have a function that returns a pointer to a parent class -- it looks > at its arguments, and then makes a new object (with new) either of > child class A, or B, depending on the arguments to this function. The > decision is made in a conditional expression, and the result is > returned: > > Parent * MakeIt(...) > { > ... > return ( <cond> ? new A(...) : new B(...) ); > } > > g++ warns that the two expressions are of different types, and so does > MPW C++. My initial reaction was that this is a compiler error. ARM, p.78, lays out the rules for correctly formed conditional expressions: "If both the second and the third expressions are of arithmetic type, the usual arithmetic conversions are performed to bring them to a common type. Otherwise, if both the second and the third expressions are either a pointer or a constant expression that evaluates to 0, pointer conversions are performed to bring them to a common type. Otherwise, if both the second and the third expressions are either references, reference conversions are performed to bring them to a common type. Otherwise if both the second and the third expressions are void, the common type is void. Otherwise if both the second and the third expressions are the same class T, the common type is T. Otherwise the expression is illegal." I tried the following code, and got the same kind of error from the ATT v2.1 compiler. I still think it looks right. Anybody see something that I missed? class Parent { }; class A : public Parent { public: A(int); }; class B : public Parent { public: B(int); }; Parent* F(int i) { return (i ? new A(i) : new B(i)); // error: type mismatch: A * ?: B * }
rae@alias.com (Reid Ellis) (04/30/91)
Josh Mittleman <mittle@blinn.watson.ibm.com> writes: >My initial reaction was that this is a compiler error. ARM, p.78, lays out >the rules for correctly formed conditional expressions: > >"If both the second and the third expressions are of arithmetic type, the >usual arithmetic conversions are performed to bring them to a common type. >Otherwise, if both the second and the third expressions are either a >pointer or a constant expression that evaluates to 0, pointer conversions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >are performed to bring them to a common type. Otherwise, if both the >second and the third expressions are either references, reference +++++++++ >conversions are performed to bring them to a common type. Otherwise if ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >both the second and the third expressions are void, the common type is >void. Otherwise if both the second and the third expressions are the same >class T, the common type is T. Otherwise the expression is illegal." I think the problem is in the "^^" marked phrase above. On first reading, it would seem to indicate "(a pointer that evaluates to 0) or (a constant expression that evaluates to 0)". But after some thought, and especially after reading the section marked with "+" above, it would seem that that phrase should be read as "(a pointer) or (a constant expression that evaluates to 0)". Is this the case? Are ?: expressions broken in AT&T cfront derivatives for this reason? Is the ANSI draft more explicit on this? "... and what about.. Naomie?" -- Electric Company Reid -- Reid Ellis 1 Trefan Street Apt. E, Toronto ON, M5A 3A9 rae@utcs.toronto.edu || rae@alias.com CDA0610@applelink.apple.com || +1 416 362 9181 [work]
mittle@blinn.watson.ibm.com (Josh Mittleman) (05/01/91)
>"If both the second and the third expressions are of arithmetic type, the >usual arithmetic conversions are performed to bring them to a common type. >Otherwise, if both the second and the third expressions are either a >pointer or a constant expression that evaluates to 0, pointer conversions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >are performed to bring them to a common type. Otherwise, if both the >second and the third expressions are either references, reference +++++++++ >conversions are performed to bring them to a common type. Otherwise if ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >both the second and the third expressions are void, the common type is >void. Otherwise if both the second and the third expressions are the same >class T, the common type is T. Otherwise the expression is illegal." In article <1991Apr29.173219.29532@alias.com>, rae@alias.com (Reid Ellis) writes: > I think the problem is in the "^^" marked phrase above. On first > reading, it would seem to indicate "(a pointer that evaluates to 0) or > (a constant expression that evaluates to 0)". But after some thought, > and especially after reading the section marked with "+" above, it > would seem that that phrase should be read as "(a pointer) or (a > constant expression that evaluates to 0)". Good point. It has also been pointed out that the problem of converting two pointers to a common type is non-trivial, and may be indeterminate if the two classes have two common base classes. This last case *must* generate an error, and it is not obvious how to design a conversion scheme that could distinguish this case from other, determinate cases. =========================================================================== Josh Mittleman (mittle@watson.ibm.com or joshua@paul.rutgers.edu) J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY 10598
rfg@NCD.COM (Ron Guilmette) (05/12/91)
In article <1991Apr29.173219.29532@alias.com> rae@alias.com (Reid Ellis) writes: > >Is this the case? Are ?: expressions broken in AT&T cfront >derivatives for this reason? Is the ANSI draft more explicit on this? Wel,, since you mentioned the rule which says that any constant expression which evaluates to zero can stand in for a NULL pointer, I'd have to say "Yes, cfront is broken". I don't think that it's just the interaction with ?: however that brings this to light. As I recall there are lots of contexts in which a null pointer value should be acceptable but where an expression like "5+7-2-10" will get you an error. -- // Ron ("Loose Cannon") Guilmette // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // New motto: If it ain't broke, try using a bigger hammer.