Topic: Language lawyers: template operator selection


Author: tslettebo@chello.no.nospam (=?iso-8859-1?Q?Terje_Sletteb=F8?=)
Date: Wed, 2 Jul 2003 13:54:17 +0000 (UTC)
Raw View
"Daniel Frey" <daniel.frey@aixigo.de> wrote in message
news:bdredp$q1s$1@swifty.westend.com...

>a) operator*(float,float) is intended and thus A is casted to float
>b) No unambiguous operator* can be selected
>
>In my initial post, I mentioned that I expect the MSVC and GCC to be
>correct. Why did I think so? Because it's IMHO a better situation for
>the user. If a) is true, the language/compiler selects conversions from
>UDTs on it's own. If it's b), the designer of the UDT has to add
>operators to his/her class to allow multiplication with float, etc.

I think it's reasonable that for a type X with a templated conversion
operator, X + Y, where Y is a fundamental type, X gets converted to Y,
if Y + Y is valid. I don't think this gives any surprises, and if you
want to make an explicit choice, you can always do so with a cast.

I think having to add operators or explicit casts, in a situation where
the compiler can do a good choice, is unnecessary inconvenience. After
all, we have rules for selections of overloads, etc., to avoid having to
explicitly specify things, and the compiler does what's supposed to be
an intuitive selection.

In other words, e.g. double + double could be considered a better match
than float + double, as the latter requires an additional conversion.

>Thus, a) is convenient if it matches the users expectations and it's
>quite annoying if the user didn't expected it, thus a potential source
>of bugs. OTOH option b) asks the user to explicitly provide operators
if
>he wants to use his type with build-ins, inconvenient in some cases but
>much safer AFAICS.

What would be unsafe about it? What kind of surprises could the user
get?


Regards,

Terje

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Thu, 3 Jul 2003 02:20:16 +0000 (UTC)
Raw View
Terje Sletteb=F8 wrote:
> "Daniel Frey" <daniel.frey@aixigo.de> wrote in message
> news:bdredp$q1s$1@swifty.westend.com...
>=20
>=20
>>a) operator*(float,float) is intended and thus A is casted to float
>>b) No unambiguous operator* can be selected
>>
>>In my initial post, I mentioned that I expect the MSVC and GCC to be
>>correct. Why did I think so? Because it's IMHO a better situation for
>>the user. If a) is true, the language/compiler selects conversions from
>>UDTs on it's own. If it's b), the designer of the UDT has to add
>>operators to his/her class to allow multiplication with float, etc.
>=20
> I think it's reasonable that for a type X with a templated conversion
> operator, X + Y, where Y is a fundamental type, X gets converted to Y,
> if Y + Y is valid.

Think about that: Do you really think that *every* type X which offers a=20
template conversion operator, *whatever it models*, should be converted=20
to e.g. double if multiplied by one?

> I think having to add operators or explicit casts, in a situation where
> the compiler can do a good choice, is unnecessary inconvenience. After

If the designer of the class X want the behaviour we are talking about,=20
he can provide appropriate operators. The user won't have to explicitly=20
cast X's to float or something! For the user, convenience is intended=20
and a good thing if it's semantically correct. The designer of X is the=20
one who IMHO should have a choice, it's not up the language to make that=20
decision. Although it wouldn't be a big problem (hopefully), I just=20
wanted to mention it - not to present it as the Holy Grail. :)

Regards, Daniel

--=20
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Fri, 27 Jun 2003 17:54:05 +0000 (UTC)
Raw View
Hi,

during a discussion over at the boost mailing list (www.boost.org), we=20
came across the following "puzzle":

struct A {
    template< typename T > operator T() const;
} a;

template<> A::operator float() const
{
    return 1.0f;
}

int main()
{
    float f =3D 1.0f * a;
}

The code is compiled without errors or warnings from EDG-based compilers=20
(Comeau, Intel), but rejected from others (GCC, MSVC [7.1]). The=20
question: Who is correct? Where should I file the bug report?

To explain the problem: The EDG seems to see 1.0f*a as a call to the=20
unambiguous operator*(float,float) and thus casts 'a' to 'float'. The=20
other compilers have several operators (float*float, float*double,=20
float*int, ...) available and thus can't decide which cast is=20
appropriate. I think the latter is the correct behaviour, but I'd like=20
to hear some comments from the language lawyers about the standard's=20
point of view on this problem. TIA.

Regards, Daniel

--=20
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com (Daveed Vandevoorde)
Date: Sat, 28 Jun 2003 04:15:32 +0000 (UTC)
Raw View
daniel.frey@aixigo.de (Daniel Frey) wrote:
> Hi,
>
> during a discussion over at the boost mailing list (www.boost.org), we
> came across the following "puzzle":
>
> struct A {
>     template< typename T > operator T() const;
> } a;
>
> template<> A::operator float() const
> {
>     return 1.0f;
> }
>
> int main()
> {
>     float f = 1.0f * a;
> }
>
> The code is compiled without errors or warnings from EDG-based compilers
> (Comeau, Intel), but rejected from others (GCC, MSVC [7.1]). The
> question: Who is correct? Where should I file the bug report?
>
> To explain the problem: The EDG seems to see 1.0f*a as a call to the
> unambiguous operator*(float,float) and thus casts 'a' to 'float'. The
> other compilers have several operators (float*float, float*double,
> float*int, ...) available and thus can't decide which cast is
> appropriate. I think the latter is the correct behaviour, but I'd like
> to hear some comments from the language lawyers about the standard's
> point of view on this problem. TIA.

I believe the EDG-based compiler is right.  Note that the built-in operator*
requires "usual airthmetic conversions" (see 5.6/2 and 5/9). This means that
there is no candidate taking (float, double) arguments: Only (float, float) or
(double, double).

Since your first argument is of type float, the (float, float) case is preferred
over the (double, double) case (the latter would require a floating-point
promotion).

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: d.frey@gmx.de (Daniel Frey)
Date: Sat, 28 Jun 2003 18:02:48 +0000 (UTC)
Raw View
On Sat, 28 Jun 2003 06:15:32 +0200, Daveed Vandevoorde wrote:

> I believe the EDG-based compiler is right.  Note that the built-in
> operator* requires "usual airthmetic conversions" (see 5.6/2 and 5/9).
> This means that there is no candidate taking (float, double) arguments:
> Only (float, float) or (double, double).

Thanks, I think especially 5/9 is what I was looking for. Time for
another GCC bug report :)

Regards, Daniel

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: cpdaniel@nospam.mvps.org ("Carl Daniel")
Date: Mon, 30 Jun 2003 04:33:17 +0000 (UTC)
Raw View
Daniel Frey wrote:
> On Sat, 28 Jun 2003 06:15:32 +0200, Daveed Vandevoorde wrote:
>> I believe the EDG-based compiler is right.  Note that the built-in
>> operator* requires "usual airthmetic conversions" (see 5.6/2 and
>> 5/9). This means that there is no candidate taking (float, double)
>> arguments: Only (float, float) or (double, double).
>
> Thanks, I think especially 5/9 is what I was looking for. Time for
> another GCC bug report :)

Readers may regard said bug report as filed for VC7.1 as well.

-cd

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bdawes@acm.org (Beman Dawes)
Date: Mon, 30 Jun 2003 14:59:40 +0000 (UTC)
Raw View
cpdaniel@nospam.mvps.org ("Carl Daniel") wrote in message news:<vytLa.257$wC2.184@newssvr19.news.prodigy.com>...
> Daniel Frey wrote:
> > On Sat, 28 Jun 2003 06:15:32 +0200, Daveed Vandevoorde wrote:
> >> I believe the EDG-based compiler is right.  Note that the built-in
> >> operator* requires "usual airthmetic conversions" (see 5.6/2 and
> >> 5/9). This means that there is no candidate taking (float, double)
> >> arguments: Only (float, float) or (double, double).
> >
> > Thanks, I think especially 5/9 is what I was looking for. Time for
> > another GCC bug report :)
>
> Readers may regard said bug report as filed for VC7.1 as well.

The core language experts on the C++ committee are discussing this
issue on their internal mailing list right now. It has turned up bugs
in at least one other compiler, too.

It would be great if Daveed or one of the committee's other core
experts posted a summary here once the committee's discussion runs its
course.

--Beman

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@vandevoorde.com (Daveed Vandevoorde)
Date: Tue, 1 Jul 2003 04:03:25 +0000 (UTC)
Raw View
google@vandevoorde.com (Daveed Vandevoorde) wrote:
> daniel.frey@aixigo.de (Daniel Frey) wrote:
> > Hi,
> >
> > during a discussion over at the boost mailing list (www.boost.org), we
> > came across the following "puzzle":
> >
> > struct A {
> >     template< typename T > operator T() const;
> > } a;
> >
> > template<> A::operator float() const
> > {
> >     return 1.0f;
> > }
> >
> > int main()
> > {
> >     float f = 1.0f * a;
> > }
> >
> > The code is compiled without errors or warnings from EDG-based compilers
> > (Comeau, Intel), but rejected from others (GCC, MSVC [7.1]). The
> > question: Who is correct? Where should I file the bug report?
> >
> > To explain the problem: The EDG seems to see 1.0f*a as a call to the
> > unambiguous operator*(float,float) and thus casts 'a' to 'float'. The
> > other compilers have several operators (float*float, float*double,
> > float*int, ...) available and thus can't decide which cast is
> > appropriate. I think the latter is the correct behaviour, but I'd like
> > to hear some comments from the language lawyers about the standard's
> > point of view on this problem. TIA.
>
> I believe the EDG-based compiler is right.  Note that the built-in operator*
> requires "usual airthmetic conversions" (see 5.6/2 and 5/9). This means that
> there is no candidate taking (float, double) arguments: Only (float, float) or
> (double, double).
>
> Since your first argument is of type float, the (float, float) case is preferred
> over the (double, double) case (the latter would require a floating-point
> promotion).

As Beman mentions in another message, this issue has been examined
by various Core WG members.  Unfortunately, there is no definite answer
to what effect the above code should have, but my explanation ignores
some problems in section 13.6.  A Core Issue will be opened to track the
problem(s). Until it is resolved, I don't think compilers can be faulted for
either behavior.

        Daveed

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tom_usenet@hotmail.com (tom_usenet)
Date: Tue, 1 Jul 2003 16:18:33 +0000 (UTC)
Raw View
On Sat, 28 Jun 2003 04:15:32 +0000 (UTC), google@vandevoorde.com
(Daveed Vandevoorde) wrote:

>daniel.frey@aixigo.de (Daniel Frey) wrote:
>> Hi,
>>
>> during a discussion over at the boost mailing list (www.boost.org), we
>> came across the following "puzzle":
>>
>> struct A {
>>     template< typename T > operator T() const;
>> } a;
>>
>> template<> A::operator float() const
>> {
>>     return 1.0f;
>> }
>>
>> int main()
>> {
>>     float f = 1.0f * a;
>> }
>>
>> The code is compiled without errors or warnings from EDG-based compilers
>> (Comeau, Intel), but rejected from others (GCC, MSVC [7.1]). The
>> question: Who is correct? Where should I file the bug report?
>>
>> To explain the problem: The EDG seems to see 1.0f*a as a call to the
>> unambiguous operator*(float,float) and thus casts 'a' to 'float'. The
>> other compilers have several operators (float*float, float*double,
>> float*int, ...) available and thus can't decide which cast is
>> appropriate. I think the latter is the correct behaviour, but I'd like
>> to hear some comments from the language lawyers about the standard's
>> point of view on this problem. TIA.
>
>I believe the EDG-based compiler is right.  Note that the built-in operator*
>requires "usual airthmetic conversions" (see 5.6/2 and 5/9). This means that
>there is no candidate taking (float, double) arguments: Only (float, float) or
>(double, double).

I disagree (with hesitation with an EDG guru). 13.6/12 details the
precise list of operator* overloads for built ins, and both

double operator*(float, double)
and
double operator*(double, double)

are listed there (float and double are both "promoted arithmetic
types"). The conversions just determine the type of the result (as
also mentioned in 13.6).

>Since your first argument is of type float, the (float, float) case is preferred
>over the (double, double) case (the latter would require a floating-point
>promotion).

But, since float*float and float*double should be provided by the
compiler, it should be ambiguous IMHO.

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Tue, 1 Jul 2003 23:45:53 +0000 (UTC)
Raw View
Daveed Vandevoorde wrote:
> As Beman mentions in another message, this issue has been examined
> by various Core WG members.  Unfortunately, there is no definite answer
> to what effect the above code should have, but my explanation ignores
> some problems in section 13.6.  A Core Issue will be opened to track th=
e
> problem(s). Until it is resolved, I don't think compilers can be faulte=
d for
> either behavior.

I thought about the current situation: We have two groups of compilers,=20
both groups represented by important members (VC/GCC/EDG). It's not just=20
a small bug in one or two compilers and this leads to a situation where=20
we are going to (potentially) break code anyway. There are basically two=20
options:

a) operator*(float,float) is intended and thus A is casted to float
b) No unambiguous operator* can be selected

The standard in it's current form backups a) by 5.6/2 and 5/9, but there=20
may be a problem with 13.6. I looked at that part but haven't seen any=20
obvious and immediate influence, so I'll leave it to the experts to=20
judge it.

In my initial post, I mentioned that I expect the MSVC and GCC to be=20
correct. Why did I think so? Because it's IMHO a better situation for=20
the user. If a) is true, the language/compiler selects conversions from=20
UDTs on it's own. If it's b), the designer of the UDT has to add=20
operators to his/her class to allow multiplication with float, etc.

Thus, a) is convenient if it matches the users expectations and it's=20
quite annoying if the user didn't expected it, thus a potential source=20
of bugs. OTOH option b) asks the user to explicitly provide operators if=20
he wants to use his type with build-ins, inconvenient in some cases but=20
much safer AFAICS.

To sum it up: If we have to change a fair amount of code and compilers=20
anyway - why not think about the *intended* behaviour? I'd personally=20
prefer option b) (for at least one argument being a UDT), as I prefer=20
control over convenience. Some convenience could be provided by a=20
library-based approach, the boost operators library comes to mind. I'm=20
not a member of the core WG, but I hope you also consider the above in=20
your discussions.

Regards, Daniel

--=20
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]