Hi
The following code gives me a mystical warning when compiled with Level
4 (/W4) warnings on in VisualStudio .NET 2003.
I cant understande why.
Tested it with Comeau online (http://www.comeaucomputing.com/tryitout/)
and it gives me no warnings.

Can someone explain this ???

/David


typedef unsigned char BYTE;
typedef unsigned short WORD;
int main()
{
WORD Checksum1=0;
WORD Checksum2=0;
BYTE* Buffer=new BYTE[10];
for (int i=0; i!=10; ++i)
{
Buffer[i]=4;
}
for (int i=0; i!=10; ++i)
{
Checksum1+=Buffer[i]; // warning
Checksum2=Checksum2+Buffer[i]; // OK
}
}

warning C4244: '+=' : conversion from 'int' to 'WORD', possible loss of data

Re: mystical warning with += by Ron

Ron
Thu Nov 20 11:02:36 CST 2003


"David Carlsson" <alagazam@REMOVEhome.se> wrote in message news:%23CQ79R3rDHA.2060@TK2MSFTNGP10.phx.gbl...
> Hi
> The following code gives me a mystical warning when compiled with Level
> 4 (/W4) warnings on in VisualStudio .NET 2003.
> I cant understande why.
> Tested it with Comeau online (http://www.comeaucomputing.com/tryitout/)
> and it gives me no warnings.

A compiler is free to give whatever warnings it cares to.

The issue here is you are doing an assignment from int to unsigned short.
It may lose data if the value of the int variable is larger than can be represented
in unsigned short (for VC++ on Pentiums, 65535).



Re: mystical warning with += by Murrgon

Murrgon
Thu Nov 20 12:13:57 CST 2003

David Carlsson wrote:
> typedef unsigned char BYTE;
> typedef unsigned short WORD;
> int main()
> {
> WORD Checksum1=0;
> WORD Checksum2=0;
> BYTE* Buffer=new BYTE[10];
> for (int i=0; i!=10; ++i)
> {
> Buffer[i]=4;
> }
> for (int i=0; i!=10; ++i)
> {
> Checksum1+=Buffer[i]; // warning
> Checksum2=Checksum2+Buffer[i]; // OK
> }
> }
>
> warning C4244: '+=' : conversion from 'int' to 'WORD', possible loss of
> data
>


Ron Natalie wrote:
> The issue here is you are doing an assignment from int to unsigned short.
> It may lose data if the value of the int variable is larger than can be represented
> in unsigned short (for VC++ on Pentiums, 65535).

This looks rather odd to me. The 'Buffer' variable is declared as a
'BYTE*' so this should mean that Buffer[i] should give you a byte.
Last time I checked a byte was eight bits and a WORD (on a MSWin
compiler) was 16 bits. Therefore there is no way that you could
"lose data" when copying a byte to a WORD.

What is probably happening is that the += operator is converting your
byte to an int before it is doing the addition and as a result you
get the warning. If this is the case though, you would think that
the compiler would be consistent and produce the same error for your
'Checksum2' variable.

Murrgon


Re: mystical warning with += by Ron

Ron
Thu Nov 20 14:48:03 CST 2003


"Murrgon" <murrgon@hotmail.com> wrote in message news:%23xBUlH5rDHA.556@TK2MSFTNGP11.phx.gbl...

> What is probably happening is that the += operator is converting your
> byte to an int before it is doing the addition and as a result you
> get the warning. If this is the case though, you would think that
> the compiler would be consistent and produce the same error for your
> 'Checksum2' variable.
>
Yes, I thought you'd understand that. You have to realize when you mix
data types the compiler goes through a set of promotions and conversions
to match the types.

Unsigned char and unsigned short are both promoted to int before the
addition step, the as I said, the assignment loses precision.



Re: mystical warning with += by Nick

Nick
Thu Nov 20 16:10:11 CST 2003

"Ron Natalie" <ron@sensor.com> wrote in message
news:3fbce156$0$206$9a6e19ea@news.newshosting.com...
>
> "Murrgon" <murrgon@hotmail.com> wrote in message
news:%23xBUlH5rDHA.556@TK2MSFTNGP11.phx.gbl...
>
> > What is probably happening is that the += operator is converting your
> > byte to an int before it is doing the addition and as a result you
> > get the warning. If this is the case though, you would think that
> > the compiler would be consistent and produce the same error for your
> > 'Checksum2' variable.
> >
> Yes, I thought you'd understand that. You have to realize when you mix
> data types the compiler goes through a set of promotions and conversions
> to match the types.
>
> Unsigned char and unsigned short are both promoted to int before the
> addition step, the as I said, the assignment loses precision.

Still it seems to me that there's a bit of an inconsistency.

Statements

(1) x+=y

and

(2) x=x+y

should behave the same but it seems that the compiler treats (1) as an
assignment operator (therefore it promotes and checks the right-hand-side
operator). However (1) does not assign y to x but adds y it to x. How will
precision be lost when 'BYTE' is extended to 'int' and then truncated to
'WORD'?

Nick



Re: mystical warning with += by Ron

Ron
Thu Nov 20 17:46:44 CST 2003


"Nick Savoiu" <savoiu@ics_.uci_.edu_> wrote in message news:%23MXQ0M7rDHA.2340@TK2MSFTNGP12.phx.gbl...

>
> should behave the same but it seems that the compiler treats (1) as an
> assignment operator (therefore it promotes and checks the right-hand-side
> operator). However (1) does not assign y to x but adds y it to x.

Actually, it's perfectly consistant. The standard says
A += B
is the same as
A = A + B
with the exception that A is evaluated only once.


> How will
> precision be lost when 'BYTE' is extended to 'int' and then truncated to
> 'WORD'?

Because you migyht add 255 to 65535 (both which fit in the respective BYTE
and WORD type) yielding 65790, a perfectly valid int, that can not be assigned
without losing information to WORD.




Re: mystical warning with += by Nick

Nick
Thu Nov 20 18:55:45 CST 2003

"Ron Natalie" <ron@sensor.com> wrote in message
news:3fbd0b36$0$35134$9a6e19ea@news.newshosting.com...
>
> "Nick Savoiu" <savoiu@ics_.uci_.edu_> wrote in message
news:%23MXQ0M7rDHA.2340@TK2MSFTNGP12.phx.gbl...
>
> >
> > should behave the same but it seems that the compiler treats (1) as an
> > assignment operator (therefore it promotes and checks the
right-hand-side
> > operator). However (1) does not assign y to x but adds y it to x.
>
> Actually, it's perfectly consistant. The standard says
> A += B
> is the same as
> A = A + B
> with the exception that A is evaluated only once.

I don't think the evaluation part is relevant here. However the "If the left
operand is not of class type, the expression is implicitly converted (clause
4) to the cv-unqualified type of the left operand. (5.17.3)" seems to mean
to me that B in A+=B should be converted to A's type.

> > How will
> > precision be lost when 'BYTE' is extended to 'int' and then truncated to
> > 'WORD'?
>
> Because you migyht add 255 to 65535 (both which fit in the respective BYTE
> and WORD type) yielding 65790, a perfectly valid int, that can not be
assigned
> without losing information to WORD.

The B should be converted to WORD not 'int' before it is added to A. So no
loss of precision would occur.

Nick



Re: mystical warning with += by harry_bosch

harry_bosch
Thu Nov 20 22:16:32 CST 2003

"Nick Savoiu" <savoiu@ics_.uci_.edu_> wrote:

> The B should be converted to WORD not 'int' before it is added to A.
> So no loss of precision would occur.

Your reasoning makes perfect sense to me, Nick, and the compiler's "rules",
in this case, don't. Unfortunately, I doubt we will produce any change in
this odd behavior of the compiler. C++ is far from perfect, so we live with
its defects and move on (hopefully :-)

--
harry

(Now Playing: Tristi ricordi - Ennio Morricone)