Hot!warning 373 implicit signed to unsigned conversion

Author
the.mark.robertson
New Member
  • Total Posts : 13
  • Reward points : 0
  • Joined: 2018/01/08 12:00:17
  • Location: 0
  • Status: offline
2018/01/09 02:55:31 (permalink)
0

warning 373 implicit signed to unsigned conversion

Hi - can someone advise why I am getting warning 373 on a line such as this:
 
  _output(pD, (uint8_t)pPCM->ShiftBuffer.Buffer & mask);
 
The warning is on the 2nd var (not the pD).
Mask is uint8_t.  .Buffer is uint16_t which I am casting as uint8_t.
uint8_t is typedef as unsigned char
uint16_t is typedef as unsigned short
_output is: static void _output(SPDEVICE* pPCM, uint16_t value);
 
I am also getting this warning on summations such as (uint8_t)val + (1000U) + (1U) which seems peculiar as every element is unsigned yet, for some reason, it seems to be warning it is doing a signed summation.
 
I know I can add casting to get rid of the warning but I should not have to.
 
Thanks
 
 
#1

18 Replies Related Threads

    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 11:57:03 (permalink)
    0
    The unsigned char objects are integer promoted to signed int for the operation and the result is signed int, which is then converted to unsigned for the target.
     
    <edit> This
    (uint8_t)val + (1000U) + (1U)
    should be okay as this result is unsigned int and should not generate that warning.
     
     
    post edited by 1and0 - 2018/01/09 12:40:51
    #2
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 12:12:46 (permalink)
    0
    (uint8_t)val +

     
    This probably isn't doing what you think it's doing, because it's just going to be converted right back to a signed int by the + operator doing integer promotion.  If your goal is to end up with an unsigned LSB, you might want to do something like
     
    (uint16_t)(uint8_t)val
     
    or if it's already an 8-bit value, just cast to uint16_t.
    #3
    the.mark.robertson
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2018/01/08 12:00:17
    • Location: 0
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 12:17:03 (permalink)
    0
    Hi.  I accept your description but dispute that this is standard compiler behavior.  An AND operation on two uint8_t leads to a signed result?  Nope. Take my second example: a simple uint8_t is increased by two defined constants (both U) and I am getting a signed number (ie this Warning).   Why should that lead to a warning or require me to work out the Warning by casting?  Again, nope.
     
    Anyway, thanks all.
     
    #4
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 12:44:33 (permalink)
    +1 (1)
    a simple uint8_t is increased by two defined constants (both U) and I am getting a signed number (ie this Warning).


    You're not "getting a signed number".  The warning is telling you that it's converting a signed value to an unsigned value, which is something you might not expect, hence the warning.
    #5
    the.mark.robertson
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2018/01/08 12:00:17
    • Location: 0
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 12:48:32 (permalink)
    0
    yes, I am getting a signed number.  XC8 is adding two uint8_t and coming up with a signed number which I am then expected to cast back to an unsigned.  It is a bug.
     
    My example: (uint8_t)val + (1000U) + (1U) 
     
    There is not a single signed number so why is the compiler giving me one?  Yes, a U8 + U8 may result in a U16 but never a I16.
     
     
    #6
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 13:03:07 (permalink)
    +1 (1)
    U8 + U8 may result in a U16 but never a I16.

     
    U8 + U8 will *always* result in an I16 when "int" is 16 bits.

    This is how C's integer promotions work.  The + operator promotes its operands to plain signed int in this case.
    #7
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 13:07:54 (permalink)
    #8
    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 13:20:01 (permalink)
    0
    John, my XC8 v1.44 is _not_ generating warning 373 for 
    (uint8_t)val + (1000U) + (1U)

     
    Perhaps the last paragraph of 6.3.1.8 integer promotion applies here.?!
     
    post edited by 1and0 - 2018/01/10 06:03:28
    #9
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 13:29:48 (permalink)
    0
    1and0
    John, my XC8 v1.44 is _not_ generating warning 373 for 
    (uint8_t)val + (1000U) + (1U)



    I don't think we've seen the real code that generates the warning, so something else might be involved.  (And Mark has acknowledged that this warning can be issued spuriously).
    #10
    HJonker
    Super Member
    • Total Posts : 489
    • Reward points : 0
    • Joined: 2006/04/19 02:17:59
    • Location: NL
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/09 23:35:01 (permalink)
    0
    What I have seen sofar is that integer promotion takes place whenever an expression contains elements of different types. Since 1000 (with or without u) has a type different from uint8_t, integer promotion WILL take place and ALL elements of the expression WILL be promoted to int.

    Kind Regards,
    Hans Jonker
    (Amsterdam, Holland)
    #11
    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/10 04:40:06 (permalink)
    0
    jtemples
    (uint8_t)val +

     
    This probably isn't doing what you think it's doing, because it's just going to be converted right back to a signed int by the + operator doing integer promotion.  If your goal is to end up with an unsigned LSB, you might want to do something like
     
    (uint16_t)(uint8_t)val
     
    or if it's already an 8-bit value, just cast to uint16_t.

    I am not so sure about that now. Integer promotion always hurts my head. ;)
     
    Here are the rules of integer promotion:
    §6.3.1.8 of the C Standard
    Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
    • If both operands have the same type, then no further conversion is needed.
    • Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
    • Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
    • Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
    • Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

    So, for this
    (uint8_t)val + (1000U) + (1U)

    (uint8_t) and U (uint16_t) are different types, and all operands are unsigned integer types. Since (uint8_t) has lesser rank than (uint16_t), (uint8_t) is converted to an unsigned int, not a signed int, by the + operator. The result of two unsigned int is unsigned; therefore, this should not generate warning 373.
    #12
    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/10 06:09:03 (permalink)
    0
    ... or is it (uint8_t) promoted to signed int, and then is converted to unsigned int for the + operation?
     
    #13
    mbrowning
    Just a Member
    • Total Posts : 1246
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: online
    Re: warning 373 implicit signed to unsigned conversion 2018/01/10 06:24:08 (permalink)
    0
    Oww. Now my head hurts

    Oh well - there's always next year
    #14
    jtemples
    Super Member
    • Total Posts : 11077
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/10 10:46:40 (permalink)
    +1 (1)
    1and0
    ... or is it (uint8_t) promoted to signed int, and then is converted to unsigned int for the + operation?

     
    I don't think the standard actually calls for that intermediate step, but I was speculating maybe that's how the compiler does it internally and is what triggers the warning.
    #15
    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2018/01/11 10:46:00 (permalink)
    0
    jtemples
    1and0
    John, my XC8 v1.44 is _not_ generating warning 373 for 
    (uint8_t)val + (1000U) + (1U)

    I don't think we've seen the real code that generates the warning, so something else might be involved.  (And Mark has acknowledged that this warning can be issued spuriously).

    I guess we will never know. OP does not seem to report back. :(
     
    #16
    boatbodger
    Starting Member
    • Total Posts : 33
    • Reward points : 0
    • Joined: 2011/03/27 15:39:07
    • Location: 0
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2019/02/18 02:46:27 (permalink)
    +1 (1)
    I too am seeing many of these warnings, even when manipulating  all unsigned, all 8-bit variables.
    The trouble is that with all these warnings, one tends to get 'warning blind' - Just now I nearly missed another warning that there was an invalid pointer conversion - that was a genine one - a missing indirection * which would have caused problems.  But it's hard to spot in the clutter caused by this weird (albeit possibly 'standard') behaviour.
     
    In short, I don't think it's progress!
    #17
    moser
    Super Member
    • Total Posts : 427
    • Reward points : 0
    • Joined: 2015/06/16 02:53:47
    • Location: Germany
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2019/02/18 09:01:07 (permalink)
    +1 (1)
    Many people forget (or do not know), that there are two kinds of implicit type changes: By rule 6.3.1.1 (Integer promotions) and by 6.3.1.8 (Usual arithmetic conversion). Often people mix up the conversion and promotion. And probably that is why others don't even understand, that there are two steps, and often look up only half of the process.
     
    I think 1and0 is (at least mostly) correct, but he also did mix up the terms for the conversion and promotion:
    1and0
    Here are the rules of integer promotion:
    §6.3.1.8 of the C Standard
    Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:[...]

    What he postet, is from 6.3.1.8 and those are not the rules of the "integer promotion". Those are the rules of the "usual arithmetic conversion". Only the first step of the "usual arithmetic conversion" is to apply the "integer promotion". Note the word "Then".
     
     
    Either read 6.3.1.1 or read the top voted answer of Lundin at this question:
    https://stackoverflow.com...t-type-promotion-rules
     
    In section "The integer promotion" Lundin tells you, that according to the rules the result of "(uint8_t)pPCM->ShiftBuffer.Buffer & mask" is (signed) int. That happens, because you used "small integers" in your expression (with rank smaller or equal than int). So they get converted to (signed) int. Then the bitwise AND is done and the result is still (signed) int. And you are assigning this to the parameter "value" which is uint16_t. Hence you get a warning, that your (signed) int is implicitly converted to an unsigned (the uint16_t).
     
     
    And yes, this is incredibly confusing. I always have to look up the rules, too. On first sight, I also thought, there can't be such an issue with the given code.
     
     
    1and0
    (uint8_t)val + (1000U) + (1U)
    1and0... or is it (uint8_t) promoted to signed int, and then is converted to unsigned int for the + operation?
    I think you are right here. First the promotion. Then the rest of the "usual conversion" with the case "operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand".
    #18
    1and0
    Access is Denied
    • Total Posts : 8740
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: warning 373 implicit signed to unsigned conversion 2019/02/18 10:10:15 (permalink)
    0
    moser
    Many people forget (or do not know), that there are two kinds of implicit type changes: By rule 6.3.1.1 (Integer promotions) and by 6.3.1.8 (Usual arithmetic conversion). Often people mix up the conversion and promotion. And probably that is why others don't even understand, that there are two steps, and often look up only half of the process.
     
    I think 1and0 is (at least mostly) correct, but he also did mix up the terms for the conversion and promotion:
    ... 
    Either read 6.3.1.1 or read the top voted answer of Lundin at this question:
    https://stackoverflow.com...t-type-promotion-rules
    ... 
    And yes, this is incredibly confusing. I always have to look up the rules, too.

    I did say it "always hurts my head." ;)  Thanks for the correction and the stackoverflow.com link.
    #19
    Jump to:
    © 2019 APG vNext Commercial Version 4.5