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

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

 




On Sun 20/04/08 11:55 AM , Christian Böhme monodhs@xxxxxx sent:
> Tom St Denis wrote:
> 
> > What type is the expression -(b * 2u)?
> 
> It _should_ be that of the destination type of the whole expression.
> 
> and thus integral conversion of an rvalue applied.

But it isn't.  The process works like this, you end up with 2^32 - 16, which is a
positive unsigned number.  This then gets zero extended (since it's unsigned) and
stored in a 64-bit integer.

How is what you wrote any different from 

a = 4294967280UL;

> 2^32 - 16 is not what -(b * 2u) expresses.  The result of x = b * 2u

Numerically, that's what it does.  you took 8, doubled it, then negated it as a
32-bit two's complement.  Then you took that unsigned expression and stored it in
a 64-bit type.

So effectively, you are doing 

a = 4294967280UL;

I ask again.  Why would that be sign extended?

You're right that a conversion is applied before being stored, but the conversion
rule applies to the = operator, nothing else.  So you have an expression who's
result is converted to a signed 64-bit int.  And the rule states that from a
32-bit unsigned value that it will be zero extended.  Otherwise, the above
statement ends with -16 in a which is not what you're doing.

> > Why does this work when your example does not?
> 
> For once, it does not give exact sizes for the objects in use.
> 
> Secondly, the type cast is acually redundant to the original version.
> 
> Finally, the example may work for b = 8 but not for b = 0xffffffff
> 
> and hence is _wrong_ with b being a _variable_ whose value no
> 
> compiler can ever predict an therefore _should_ use a temporary
> 
> with an appropriate type which, again, is the point of the
> 
> whole discussion.
> 

I have no idea what you're talking about.

b = 0xFFFFFFFF * 2 would get you 0xFFFFFFFE which btw is congruent to -2 mod
2^32.  However, if you do 

long long a = 0xFFFFFFFEUL;

a == -2 will be false, since it's not sign extended.

Using your logic ...

float a = 3;
int b;

b = a / 1.5;

What is the value that should be in b?  Well if we convert first we get 

b = 3 / 1 [or 2]

so b is either 3 or 1.  How is that advantageous?  Instead, what ACTUALLY happens
is the division occurs first, resulting in a float of 2, then that is converted
before being stored in b.  

I suggest you read either the C standard or at least the K&R C book and learn
about conversion rules, variable promotions, etc...

In short, if you want signed arithmetic and expressions, use signed variables [or
cast them to a signed type].  Negating an unsigned variable or expression is not
usually a good idea [or particularly useful].  

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

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