EmbeddedRelated.com
Forums

Compiler bug or my mistake?

Started by Vladimir Vassilevsky October 25, 2012
IAR AVR ECPP
Overloaded function:

void foo(u8 x);
void foo(s16 x);

It appears that foo('A') calls s16 version of function, as if  'A'  is int.
However foo((u8)'A') calls u8 version of function, as it is supposed to be.

Is this my mistake or compiler bug ?

VLV
 


In article <q7CdnbJNwa8V5xTNnZ2dnUVZ5hydnZ2d@giganews.com>,
Vladimir Vassilevsky <nospam@nowhere.com> wrote:
>IAR AVR ECPP >Overloaded function: > >void foo(u8 x); >void foo(s16 x); > >It appears that foo('A') calls s16 version of function, as if 'A' is int. >However foo((u8)'A') calls u8 version of function, as it is supposed to be. > >Is this my mistake or compiler bug ?
I don't know that compiler, but does it default to signed char or unsigned ? That may be the source of the confusion. Nick -- "The Internet, a sort of ersatz counterfeit of real life" -- Janet Street-Porter, BBC2, 19th March 1996
On 2012-10-25, Vladimir Vassilevsky <nospam@nowhere.com> wrote:
> IAR AVR ECPP > Overloaded function: > > void foo(u8 x); > void foo(s16 x); > > It appears that foo('A') calls s16 version of function, as if 'A' is int. > > However foo((u8)'A') calls u8 version of function, as it is supposed to be. > > Is this my mistake or compiler bug ?
In C 'A' is an int. (I'm sure about that.) But I _thought_ that in C++ 'A' was a char. Looks like compiler bug to me. The justification I once read for that change between C and C++ specifically said it was so that overloaded functions would do what you expected when passed a literal character constant like 'A'. -- Grant Edwards grant.b.edwards Yow! Is my fallout shelter at termite proof? gmail.com
On Thu, 25 Oct 2012 17:58:26 +0000, Grant Edwards wrote:

> On 2012-10-25, Vladimir Vassilevsky <nospam@nowhere.com> wrote: >> IAR AVR ECPP >> Overloaded function: >> >> void foo(u8 x); >> void foo(s16 x); >> >> It appears that foo('A') calls s16 version of function, as if 'A' is >> int. >> >> However foo((u8)'A') calls u8 version of function, as it is supposed to >> be. >> >> Is this my mistake or compiler bug ? > > > In C 'A' is an int. (I'm sure about that.) > > But I _thought_ that in C++ 'A' was a char. Looks like compiler bug to > me. The justification I once read for that change between C and C++ > specifically said it was so that overloaded functions would do what you > expected when passed a literal character constant like 'A'.
I generally count it as a mistake to assume that the compiler is going to be an absolute stickler for conforming to standards. You can generally count on correct behavior on the well-trodden paths, but not in the corner cases. It's sad, but it's saved my ass numerous times. -- My liberal friends think I'm a conservative kook. My conservative friends think I'm a liberal kook. Why am I not happy that they have found common ground? Tim Wescott, Communications, Control, Circuits & Software http://www.wescottdesign.com
Op 25-Oct-12 19:44, Vladimir Vassilevsky schreef:
> IAR AVR ECPP > Overloaded function: > > void foo(u8 x); > void foo(s16 x); > > It appears that foo('A') calls s16 version of function, as if 'A' is int. > However foo((u8)'A') calls u8 version of function, as it is supposed to be. > > Is this my mistake or compiler bug ?
If the char type is not exactly the same as the u8 type and the s16 type is the same as the int type on your platform the compiler might conclude that with an implicit promotion to int (it doesn't take much to trigger this) the s16 version of foo is a better match than the u8 version of foo. I tried it with Visual Studio 2010 with the following code: void foo(unsigned char x); void foo(int x); I see that foo('A') calls the int version. If I replace unsigned char with signed char it still calls the int version. Only if I leave out unsigned/signed the char version gets preferred over the int version. I'm not a language lawyer, but I'm inclined to believe it is your mistake ;-)
On 2012-10-25, Tim Wescott <tim@seemywebsite.com> wrote:
> On Thu, 25 Oct 2012 17:58:26 +0000, Grant Edwards wrote: > >> On 2012-10-25, Vladimir Vassilevsky <nospam@nowhere.com> wrote: >>> IAR AVR ECPP >>> Overloaded function: >>> >>> void foo(u8 x); >>> void foo(s16 x); >>> >>> It appears that foo('A') calls s16 version of function, as if 'A' is >>> int. >>> >>> However foo((u8)'A') calls u8 version of function, as it is supposed to >>> be. >>> >>> Is this my mistake or compiler bug ? >> >> >> In C 'A' is an int. (I'm sure about that.) >> >> But I _thought_ that in C++ 'A' was a char. Looks like compiler bug to >> me. The justification I once read for that change between C and C++ >> specifically said it was so that overloaded functions would do what you >> expected when passed a literal character constant like 'A'. > > I generally count it as a mistake to assume that the compiler is going to > be an absolute stickler for conforming to standards.
I would say that C compilers are generally a lot better at standards compliance than C++ compilers. The C language is a lot simpler and it's been around a lot longer, so that's no surprise...
> You can generally count on correct behavior on the well-trodden > paths, but not in the corner cases. > > It's sad, but it's saved my ass numerous times.
-- Grant Edwards grant.b.edwards Yow! Hello. I know at the divorce rate among gmail.com unmarried Catholic Alaskan females!!
On 25/10/12 20:35, Dombo wrote:
> Op 25-Oct-12 19:44, Vladimir Vassilevsky schreef: >> IAR AVR ECPP >> Overloaded function: >> >> void foo(u8 x); >> void foo(s16 x); >> >> It appears that foo('A') calls s16 version of function, as if 'A' is >> int. >> However foo((u8)'A') calls u8 version of function, as it is supposed >> to be. >> >> Is this my mistake or compiler bug ? > > If the char type is not exactly the same as the u8 type and the s16 type > is the same as the int type on your platform the compiler might conclude > that with an implicit promotion to int (it doesn't take much to trigger > this) the s16 version of foo is a better match than the u8 version of foo. > > I tried it with Visual Studio 2010 with the following code: > > void foo(unsigned char x); > void foo(int x); > > I see that foo('A') calls the int version. If I replace unsigned char > with signed char it still calls the int version. Only if I leave out > unsigned/signed the char version gets preferred over the int version. > > I'm not a language lawyer, but I'm inclined to believe it is your > mistake ;-) > >
In C++, a "char" is a distinct type, separate from "signed char" and "unsigned char". So it is not surprising that you get a match for 'A' with a plain "char". But I also think it's a little odd that when no "foo(char x)" is found, "foo(int x)" is tried before "signed char" or "unsigned char" versions. Maybe the OP could cross-post to comp.lang.c++ - some of the people there /are/ language lawyers.
Vladimir Vassilevsky wrote:
> IAR AVR ECPP > Overloaded function: > > void foo(u8 x); > void foo(s16 x); > > It appears that foo('A') calls s16 version of function, as if 'A' is int. > However foo((u8)'A') calls u8 version of function, as it is supposed to be. > > Is this my mistake or compiler bug ? > > VLV > > >
Neither. "short a = 'A';" is perfectly good 'C'. 'A' is just a macro for an integer. -- Les Cargill
Les Cargill wrote:
> Vladimir Vassilevsky wrote: >> IAR AVR ECPP >> Overloaded function: >> >> void foo(u8 x); >> void foo(s16 x); >> >> It appears that foo('A') calls s16 version of function, as if 'A' is >> int. >> However foo((u8)'A') calls u8 version of function, as it is supposed >> to be. >> >> Is this my mistake or compiler bug ? >> >> VLV >> >> >> > > > Neither. "short a = 'A';" is perfectly good 'C'. 'A' is just a macro for > an integer. > > -- > Les Cargill
Oops! Reading is *fun*damental - you said ECPP - in C++, 'A' is a char. I imagine the IAR compiler prematurely promoted it to a short. I don't trust *any* of the language features in *any* of the IAR compilers. Might be worth a #ifdef __cplusplus #error YesC++ #endif to see what mode the compiler thinks it's in there. Also print out "sizeof('A')". -- Les Cargill
Grant Edwards wrote:
> On 2012-10-25, Vladimir Vassilevsky <nospam@nowhere.com> wrote: >>void foo(u8 x); >>void foo(s16 x); >> >>It appears that foo('A') calls s16 version of function, as if 'A' is int. >>However foo((u8)'A') calls u8 version of function, as it is supposed to be. > > In C 'A' is an int. (I'm sure about that.) > > But I _thought_ that in C++ 'A' was a char. Looks like compiler bug > to me.
A 'char' is most likely not an 'u8', which I assume to be a 'unsigned char'. If 'char' is signed, converting to 'unsigned char' is a conversion, which is a worse candidate than promoting to a 16-bit 'signed short' because that cannot lose data. Stefan