Topic: 2nd posting: Should the compiler *reallly* allow this?
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/18 Raw View
Ronald Fischer <rfi@uebemc.siemens.de> writes:
|> Assume an expression of form (A?B:C), where A is an int and B and C are of
|> different type. Under what conditions is this expression syntactically
|> correct?
This is described in section 5.16 of the draft.
|> This question arose from the following concrete problem: In the
|> program below, the definition of s is rejected by SparcWorks C++ and
|> gcc, while the definition of t is accepted:
|>
|> struct S { S(int *);}; // define conversion from int* to S
|> struct T {
|> T(int *); // define conversion from int* to T, and....
|> operator int*(); // ... from T to int*
|> };
|> void f(int flag, S s0, T t0)
|> {
|> S s(flag ? s0 : 0); // syntax error; o.k., that's what I'd expect.
|> T t(flag ? t0 : 0); // but why is THIS allowed?
|> }
|>
|> I can understand why s is rejected: After all, the types involved are S
|> and int, and while there is a conversion from 0 to S via int*, this is
|> (AFIK) not done implicitly when balancing both parts of a ?: expression.
I think that the compilers are wrong, at least according to the latest
draft. Because a class is involved, the overload resolution rules of
section 13.3.1.2 are invoked. The critical sentence is the first one in
paragraph 2: "If either operand has a type that is a class or an
enumeration, a user-defined operator function might be declared that
implements this operator or a user-defined conversion can be necessary
to convert the operand to a type that is appropriate for a built-in
operator." Since two S's are appropriate for the built-in operator `:',
the conversion 0->int*->S should be considered. There is, of course,
more following, but all of the references to the built-in operators seem
to specify "appropriate types", or something similar. There is nothing
that I could find to restrict the built-in operators to built-in types.
(The error is understandable, since in fact, ?: is the only operator
which can apply to class types, and this section is basically concerned
with operator overloading, and choosing between a user defined operator
and a built-in operator.)
Note that under these rules, the second expression is disallowed because
it is ambiguous.
I don't know what intermediate versions of the draft said, but the ARM
simply banned such expressions completely: if either side of the `:' was
a class type, both must be, and must have exactly the same type. For
portability reasons, I would recommend programming to the ARM rules, and
always using explicit casts to force the desired type.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]