Topic: Defect Report: What conversions are considered when selecting a builtin operator candidate?


Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Tue, 9 Mar 2010 12:28:11 CST
Raw View
Subject of this issue report is the following code

     struct A {
       operator char*();
     };

     void f() { A a; a[1.0]; }

13.3.1.2[over.match.oper] paragraph 7 says that any operand is converted to
the appropriate parameter and that then clause 5 is applied to these
converted operands (since they are in the context of overload
resolution, it
makes sense to interpret "converted" as meaning "implicitly converted").
Thus the operands of the builtin-op[] are "(char*, std::ptrdiff_t)" and the
use succeeds.

In early drafts from '96, 13.3.1.2[over.match.oper] paragraph 7 restricted
conversions to only class-type operands. c++98 removed that restriction and
added additional text to 5[expr] paragraph 3.

I think to forbid the above use, that paragraph says that "However, these
built-in operators participate in overload resolution, and as part of that
process user-defined conversions will be considered where necessary to
convert the operands to types appropriate for the built-in operator." -
however in my opinion it is not at all clear from this that this claims to
be an exhaustive description of all forms of conversion sequences that are
considered - rather it sounds like it just emphasizes the impact of these
conversions because the corresponding, more detailed, text in 13.3.1.2 does
not make any such restrictions.

In addition, if clause 5 does claim to be exhaustive on the conversions
that
are considered, it's not clear what happens for example to an enumeration
operand of an unary "operator+" candidate: Does the conversion fail and the
program is ill-formed, or is the conversion of that operand just not done
(as is the case in '96)?

The clang compiler does, for example, allow the above code (but forbids
"(a.operator char*())[1.0]" since no overload resolution happens for op[]),
whereas older compilers (i tested comeau/edg and gcc) forbid it.

I think 13.3.1.2 or clause 5 (i tend to say that 13.3.1.2 is the better
place for this) should make it clear that only class-type operands are
converted, and the remaining operands will undergo the tests of clause 5
unconverted.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 10 Mar 2010 08:48:26 CST
Raw View
On 9 Mrz., 19:28, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Subject of this issue report is the following code
>
>      struct A {
>        operator char*();
>      };
>
>      void f() { A a; a[1.0]; }
>
> 13.3.1.2[over.match.oper] paragraph 7 says that any operand is converted to
> the appropriate parameter and that then clause 5 is applied to these
> converted operands (since they are in the context of overload
> resolution, it
> makes sense to interpret "converted" as meaning "implicitly converted").
> Thus the operands of the builtin-op[] are "(char*, std::ptrdiff_t)" and the
> use succeeds.
>
> In early drafts from '96, 13.3.1.2[over.match.oper] paragraph 7 restricted
> conversions to only class-type operands. c++98 removed that restriction and
> added additional text to 5[expr] paragraph 3.
>
> I think to forbid the above use, that paragraph says that "However, these
> built-in operators participate in overload resolution, and as part of that
> process user-defined conversions will be considered where necessary to
> convert the operands to types appropriate for the built-in operator." -
> however in my opinion it is not at all clear from this that this claims to
> be an exhaustive description of all forms of conversion sequences that are
> considered - rather it sounds like it just emphasizes the impact of these
> conversions because the corresponding, more detailed, text in 13.3.1.2 does
> not make any such restrictions.
>
> In addition, if clause 5 does claim to be exhaustive on the conversions
> that
> are considered, it's not clear what happens for example to an enumeration
> operand of an unary "operator+" candidate: Does the conversion fail and the
> program is ill-formed, or is the conversion of that operand just not done
> (as is the case in '96)?
>
> The clang compiler does, for example, allow the above code (but forbids
> "(a.operator char*())[1.0]" since no overload resolution happens for op[]),
> whereas older compilers (i tested comeau/edg and gcc) forbid it.
>
> I think 13.3.1.2 or clause 5 (i tend to say that 13.3.1.2 is the better
> place for this) should make it clear that only class-type operands are
> converted, and the remaining operands will undergo the tests of clause 5
> unconverted.

I believe this is taken care of by

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#545

HTH & Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]