Re: Re: Integral conversions in C/C++

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun 20/04/08  3:43 PM , Christian Böhme monodhs@xxxxxx sent:
> Tom St Denis wrote:
> > But it isn't.
> That's no news.  I am interested in _why_ it is not.  I have yet to
> see a plausible explanation for the original algebraic statement why
> a does not contain a _negative_ value although a's type allows it and
> the compiler is given enough freedom to allocate a temporary large
> enough and actually technically available (which is both the case)
> to hold such a result.

Because there is no such thing as a negative unsigned number.  And the promotion
applies to the operator, you do get that = is an operator just like + and /
right?  The promotions occur (in time) with respect to the order of precedence. 
If they occur out of order you end up with nastyness (like the float example I
sent earlier).

> > Numerically, that's what it does.
> This is what is done _technically_.  In pure algebraic terms and
> 
> given the original expression, a = 4294967280UL is a colossal
> screw-up which I actually expected the compiler to warn me about.

Why?  You negated an unsigned expression.  Then assigned that unsigned value to a
larger integer type.  an unsigned promotion to a signed type [regardless of size]
does NOT include a sign extension.  Never has, never will.

If you think about that, it makes sense.  For example,

unsigned char b = 255;
int a = 4;

a += b;

Should the result be 3?  Even though 255 is technically a -1 mod 256?

How is that any different than your example?

If we followed your logic, the above statement would read

1.  promote b to a signed int (-1)
2.  add to a and store

> > I ask again.  Why would that be sign extended?
> 
> You are missing the point.  The result of b * 2u is to be multiplied
> by -1 and stored in a.  How such a simple algebraic statement can
> possibly be interpreted as some sick type conversion operation was
> the point of the original post.  Bottom line: If I wanted to use
> modulo arithmetic I'd be _explicit_ about it.

Bottom line is, if you want to work with signed data, don't use unsigned types. 
This sort of bug is probably hidden most of the time from you since if you use a
32-bit int, you'll get the negative value you want (but just by mere coincidence
since they're both two's complement).

> > You're right that a conversion is applied before being
> stored, but the conversion
> > rule applies to the = operator, nothing else.
> 
> Interesting.  Can you point me to the section(s) in the standard(s)
> where temporary expressions are explicitly left out from integral
> conversions ?

They are converted, but to the type of the expression (multiple promotions may
occur).  For example:

signed char a;
short b;
int c;
long long d;

d = d + (c + (b + a));

a is an expression of type signed char.  b+a is of type short, c + ... is type
int, and so on.

The result of the expressions are promoted (converted) to the appropriate type. 
So if you had b = c = d = 0, and a = -1, then the result would be d = -1.  Now
change a to unsigned char and see what happens.  All of a sudden d is equal to
255.  Amazing!  Apparently if you add 255 to a larger data type it doesn't get
interpreted as negative!

> > I have no idea what you're talking about.
> 
> You will in a couple of years.

All those having problem understanding the C [and C++] standards raise your hand
(hint: this is embarrassing, but please raise your hand!!!).

> That's a completely different problem dealing with _floating point_
> conversions (C++ 4.8) and irrelevant to the one I was describing.

Actually, it's the exact same thing.  The rules for promoting/converting
regarding the = operator don't change just because you're using a float or heck
even a structure!!!

> It appears that you did not read the original post thoroughly as
> that contained explicit references to the C++ standard.

C++ and C are similar in regards to promoting data types for expressions.

> > This is also totally off-topic for this list, as you're
> not
> > discussing a GCC bug.
> 
> This is gcc-help and not gcc-bugs.

And this has nothing specifically to do with GCC.  Any conforming C or C++
compiler will generate the same damn output.

And just because you're resilient to new information doesn't mean your complaints
or observations are any more correct then when you first started posting.  If you
used the language properly in the first place, you wouldn't be in this mess.  

And while I'm on a rant, I should point out that type promotions is a very BASIC
element of both the C and C++ languages, and any competent software developer
should be familiar with them like they're 2nd nature.  It'd be like the pianist
having to look up where the middle C is every time they played... can't work that
way.

Tom



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux