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

Iurii via cfe-dev cfe-dev at lists.llvm.org
Thu Jul 21 13:52:45 PDT 2016


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
> 
> 



More information about the cfe-dev mailing list