[cfe-dev] Unwanted warning on assigning negatives to unsigned bit-fields

Iurii via cfe-dev cfe-dev at lists.llvm.org
Sat Jul 30 08:51:03 PDT 2016


Are there any new discoveries on the issue?

On 21.07.2016 22:52, Iurii via cfe-dev wrote:
> Thanks for taking a look. I just want to note that this behaviour wouldn't be compatible with the C99. And if true
> it's also not consistent across different widths:
> 
>     typedef union _bf {
>         struct {
>             uint16_t field1:16;   //Warning. Assigned 0xffff
>         } fields;
>         uint16_t raw;
>     } bf;
> 
>     typedef union _bf {
>         struct {
>             uint32_t field1:32;   //No warning. Assigned 0xffffffff
>         } fields;
>         uint32_t raw;
>     } bf;
> 
>     typedef union _bf {
>         struct {
>             uint64_t field1:64;   //No warning.  Assigned 0xffffffffffffffff
>         } fields;
>         uint64_t raw;
>     } bf;
> 
> So assuming it's first converted to the unsigned int before assignment it would then assign 0xffffffff in the third
> case (which would also contradict the standard). On the other hand if -1 is first converted to the (full-width) type
> of the bit-field, then it would not generate a warning in the first case.
> 
> In any case the correct behaviour is to convert directly into the integer type consisting of the specified number of
> bits. And to be consistent with the assignment of negatives to standard unsigned integers the warning should only be
> generated for negatives that do not fit into the signed counterpart of the bit-field type consisting of the specified
> number of bits.
> 
> On 21.07.2016 20:11, Richard Trieu wrote:
>> I think what's happening is -1 has type int, then gets converted to unsigned, then assigned to the bit field.  As an
>> unsigned value, the minimum number of bits required is the full bit width, resulting in the warning.  I am look
>> further into this.
>>
>> On Mon, Jul 18, 2016 at 9:08 AM, David Blaikie <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
>>
>>     Richard - perhaps you could take a look at this diagnostic quality issues/possible inconsistency?
>>
>>
>>     On Sun, Jul 17, 2016 at 11:12 AM Iurii via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>>
>>         Hi everybody,
>>
>>         I'm suffering from an annoying warning. Here's an example to quickly reproduce it:
>>
>>             #include <stdio.h>
>>             #include <stdint.h>
>>             #include <inttypes.h>
>>
>>             typedef union _bf
>>             {
>>                 struct
>>                 {
>>                     uint32_t field1:2;
>>                     uint32_t field2:30;
>>                 } fields;
>>                 uint32_t raw;
>>             } bf;
>>
>>             int main(int argc, char *argv[])
>>             {
>>                 printf("0x%" PRIx32 "\n"
>>                        "0x%" PRIx32 "\n",
>>                         ((bf){ .fields.field1 = -1 }).raw, //Warning
>>                         ((bf){ .raw = -1 }).raw );         //No warning
>>                 return 0;
>>             }
>>
>>         Compilation: clang -std=c99 -m32 -O2 -o test test.c
>>
>>         Result: test.c:19:37: warning: implicit truncation from 'int' to bit-field changes value from -1 to 3
>>
>>         Could someone, please, explain me, why the warning is produced? The C99 standard is very clear about the behaviour
>>         with respect to the value of field1 (the value of raw after assigning to field1 is implementation-defined, but
>>         that's
>>         a different story), and it is unambiguous:
>>
>>         6.3.1.3 paragraph 2
>>         "if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum
>>         value that can be represented in the new type until the value is in the range of the new type"
>>
>>         6.7.2.1 paragraph 9:
>>         "A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits"
>>
>>         So field1 is an unsigned integer consisting of 2 bits. The maximum value that it can store is 2^2-1 . In order to
>>         assign -1 to field1 2^2-1+1 must be added to -1. The result is therefore well-defined to be 3. So as long as
>>         assigning
>>         -1 to any standard unsigned integer does not produce any warning, I see no reason behind producing it for unsigned
>>         bit-fields. Especially because this is the most convenient way to set all bits in a bit-field. A single-bit
>>         bit-field
>>         would be a somewhat special case for assigning -1, but I'd prefer to not have the warning in this case as well.
>>
>>         Kind regards
>>         _______________________________________________
>>         cfe-dev mailing list
>>         cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-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