[cfe-dev] Fwd: [llvm-dev] Unsigned Bitwise Shift for Bit-field Structure

Shiva Chen via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 19 22:40:06 PDT 2017


Hi Hubert and Craig,

Thank you for making the case more clear.

"(f.b << 1) does not perform promotion to unsigned long long"
So (f.b << 1) is 40 bit unsigned integer and should be 0, right ?

But the bugzilla in
https://bugs.llvm.org/show_bug.cgi?id=17299
said it should be a GCC bug.

So I'm a little confused.

2017-04-20 10:51 GMT+08:00 Hubert Tong <hubert.reinterpretcast at gmail.com>:
> On Wed, Apr 19, 2017 at 10:35 PM, Craig Topper via cfe-dev
> <cfe-dev at lists.llvm.org> wrote:
>>
>> This test program prints 0.
>>
>>
>> #include <stdio.h>
>>
>> struct foo
>> {
>>   unsigned long long b:40;
>> } x;
>>
>> int main() {
>>   foo f;
>>   f.b = 0x8000000000ULL;
>>   f.b <<= 1;
>>   printf("%llx\n", f.b);
>>   return 0;
>> }
>
> Which does not answer the question. The question is whether (f.b << 1) is 0.
>
> Test:
> int printf(const char *, ...);
> int main(void) {
>   struct F { unsigned long long b : 40; } f;
>   f.b = 0x8000000000ull;
>   printf("0x%016llx\n", (unsigned long long)(f.b << 1));
> }
>
> GCC says 0. Clang says otherwise.
> Online compiler: https://wandbox.org/permlink/MNTBbjv2F96N4boA
>
> Now, the use of unsigned long long is itself a bit of an extension; however,
> yes, the wording does make it so that (f.b << 1) does not perform promotion
> of the bitfield type to unsigned long long.
>
>>
>>
>> ~Craig
>>
>> On Wed, Apr 19, 2017 at 7:28 PM, Craig Topper <craig.topper at gmail.com>
>> wrote:
>>>
>>> Adding the clang developer list and removing the llvm developer list.
>>> Clang folks would be better for asking a C++ question such as this.
>>>
>>> ~Craig
>>>
>>> On Wed, Apr 19, 2017 at 7:23 PM, Shiva Chen via llvm-dev
>>> <llvm-dev at lists.llvm.org> wrote:
>>>>
>>>> Hi,
>>>>
>>>> I have a question about unsigned bitwise shift.
>>>>
>>>> According the C99 6.5.7.4
>>>>
>>>> The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
>>>> bits are filled with zeros. If E1 has an unsigned type, the value of
>>>> the result is E1 × 2^E2, reduced modulo one more than the maximum
>>>> value representable in the result type.
>>>>
>>>> So if
>>>>
>>>> unsigned b = 0x80000000;
>>>> unsigned a = b << 1;
>>>> a will equal to 0 because a = (b << 1) mod (1<<32);
>>>> (1<< 32) is UINT_MAX+1
>>>>
>>>> For the bit-field structure defined as
>>>> struct foo
>>>> {
>>>>   unsigned long long b:40;
>>>> } x;
>>>>
>>>> According to C99 6.7.2.1
>>>> A bit-field is interpreted as a signed or unsigned integer type
>>>> consisting of the specified number of bits.
>>>> So the x.b will treat as 40 bit unsigned integer and it should follow
>>>> 6.5.7.4.
>>>>
>>>> if x.b = 0x80000000 00;
>>>> x.b << 1 = (x.b << 1) mod (1<<40)
>>>> So x.b << 1 should be 0, right ?
>>>>
>>>> Please correct me if I miss understanding something.
>>>>
>>>> Thanks,
>>>> Shiva
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>>
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>



More information about the cfe-dev mailing list