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

Hubert Tong via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 19 19:51:35 PDT 2017


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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170419/57630aa4/attachment.html>


More information about the cfe-dev mailing list