c++/3747

Jan van Dijk jan@etpmod.phys.tue.nl
Fri Oct 19 14:23:00 GMT 2001


[Please CC me, thanks]

Thank you very much for your analysis. 

Three issues remain, though:

1) If gcc-3 is correct, it seems that every other compiler out there is
wrong. Every compiler I know of accepts this code. In fact, the code
below is a stripped-down version of the string class from the widely
used cross-platform GUI toolkit `wxWindows'. By its nature, this library
is compiled on a variety of platforms/compilers: gcc's correctness is
going to break a _lot_ of existing code out there...

2) Out of curiosity, where in the standard is it stated explicitly that
0 is of type int, rather than unsigned? I did not succeed finding this.
Because you ---judging from your analysis--- have an intimate knowledge
of The Standard, perhaps you can point me in the right direction.

3) You state that operator[] should take int, rather than unsigned. In
practice, isn't it true that commonly size_t is used (in for example
libstdc++). And, isn't size_t commonly equal to `unsigned'?

I wholeheartedly agree that conversion operators as in the code below
are horrible. Fact is that I have to live with them because they occur
so frequently in the libraries I (am forced to) use. 

Thanks for your time and patience,

Sincerely yours,

Jan van Dijk.

"Rosen, Hyman" wrote:
> 
> To recap, given the code
> 
>         struct A {
>                 char operator[](unsigned) const;
>                 operator const char*() const;
>         } s;
>         char c = s[0];
> 
> gcc reports ambiguity in the choice of operators,
> which the original reporter thinks is a bug. In fact,
> gcc is correct, and the construct is ambiguous.
> 
> The analysis begins in 13.3.1.2. Because s has class
> type, we come up with two candidates for the expression
> s[0]. The first is the member operator[], which upon
> including the object for overload resolution (13.3.1/2)
> looks like the call
> 
>         A::operator[](A, unsigned)
> 
> The second candidate, which we derive from 13.3.1.2/3 and
> 13.3.3.1 is the built-in operator (13.6/13)
> 
>         operator[](const char *, ptrdiff_t)
> 
> Now, given the first candidate, the first operand requires
> no conversion, while the second does, since the type of 0
> is not unsigned. Given the second candidate, the first operand
> requires a conversion but the second does not if ptrdiff_t is
> a synonym for int. So the compiler correctly flags the expression
> as ambiguous.
> 
> The proper response to this code is to say "don't do that" and
> to once again reflect on why conversion operators are bad, and
> why subscript operators should take int and not unsigned.
> Unfortunately, this is also the code generated by CORBA
> IDL-to-C++ compilers, so you'll probably see a lot of this.



More information about the Gcc-bugs mailing list