[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-chat] Type promotion and shift operators
From: |
Rick Mann |
Subject: |
Re: [avr-chat] Type promotion and shift operators |
Date: |
Wed, 2 Feb 2011 13:28:36 -0800 |
On Feb 2, 2011, at 12:39:12, Michael Hennebry wrote:
>>
>> No, I wasn't proposing that as the code I should write. I was trying to
>> codify what you said. You said, "the type of x<<y is now the type of x after
>> the usual integer promotions":
>
> C doesn't believe is doing arithmetic on chars or shorts.
> Had x been a short it would have been promoted to int before the shift.
> In principle, y could be promoted,
> but it wouldn't affect the type of the result.
Well, neither type is char or short. int is 16 bits and signed. I think the the
literal 1 gets type int. The problem I see is this: according to my K&R C book
(which you seem to be saying is out of date), the smaller type is promoted to a
larger type when the types on an operator are different. Which led me to
believe that the 1 (an implicit int) should be promoted to uint32_t. Now, I'm
not 100% clear, because they also differ in signdedness.
But you're telling me a "quiet change" (to the language spec, I presume) means
that for the << operator, the resulting type is the type of the LHS. But you
also said "after the usual integer promotions," which I took to mean the
original behavior of C, which is to promote the size of the smaller type to
something that will fit the larger type.
So, if it first promotes, that means it does the equivalent of
((long) 1) << v
But if the result then has the type of the LHS (int), it then casts that result
to int, thereby throwing away bits. I don't know why they was considered to be
correct. If I were adding instead of shifting, it would work fine.
So, it seems wrong to me, and it makes for unnecessarily verbose code, as well
as code that has to be more carefully considered when changing the type of the
result.
--
Rick
>
>> 1) usual integer promotions (which I take to mean, in this case, the LHS is
>> promoted to the size of RHS)
>> 2) result of shift operation is type of LHS argument
>
> Not sure what this means.
> Will hope desired information is provided elsewhere.
>
>> That seems to say that my original expression:
>>
>> foo |= 1 << v;
>
> The type of 1 << v is the type of 1 which is int.
> At least for v in 0..14, this has well-defined semantics equivalent to
> foo |= (int)(1 << v);
> foo |= 1U << v;
> has well-defined semantics for nonnegative v.
> C doesn't require as much of signed types as it does of unsigned.
>
>> Behaves as if I had written this:
>>
>> foo |= (int) (((long) 1) << v); // extra parens added for clarity
>>
>> Which strikes me as terribly wrong.
>
> It is wrong.
> For v>=15, it definitely would have no well-defined semantics.
> The conversion from signed long to signed int is not value-preserving.
>
>> When was this change adopted into the language?
>
> Don't know.
>
> --
> Michael address@hidden
> "Pessimist: The glass is half empty.
> Optimist: The glass is half full.
> Engineer: The glass is twice as big as it needs to be."
- [avr-chat] Type promotion and shift operators, Rick Mann, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Michael Hennebry, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Rick Mann, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Michael Hennebry, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Rick Mann, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Michael Hennebry, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators,
Rick Mann <=
- Re: [avr-chat] Type promotion and shift operators, David A. Lyons, 2011/02/02
- Re: [avr-chat] Type promotion and shift operators, Michael Hennebry, 2011/02/02