• AVR Freaks

Hot!Another implicit signed to unsigned conversion warning

Page: 12 > Showing page 1 of 2
Author
acharnley
Super Member
  • Total Posts : 369
  • Reward points : 0
  • Joined: 2016/05/01 06:51:28
  • Location: 0
  • Status: offline
2019/04/07 06:13:28 (permalink)
0

Another implicit signed to unsigned conversion warning

I've a few which don't make any sense. Take the following-


uint8_t i = motion.frequency >= mpptMaxFrequency? mpptMaxFrequency : motion.frequency;


Both motion.frequency and mpptMaxFrequency are cast as uint8_t. 

Or this one


typedef enum
{
channel_ANA0 = 0x0,
channel_ANA3 = 0x3,
channel_ANB2 = 0xA,
channel_ANC0 = 0x10
} adcc_channel_t;

static adcc_channel_t adcChannels[] = { channel_ANA0, channel_ANA3, channel_ANB2, channel_ANC0 };

ADPCH = adcChannels[0]; // warning here

#1

27 Replies Related Threads

    andersm
    Super Member
    • Total Posts : 2653
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/07 06:37:47 (permalink)
    +5 (5)
    For the first case, the C99 standard says regarding the conditional operator
    If both the second and third operands have arithmetic type, the result type that would be determined by the usual arithmetic conversions, were they applied to those two operands, is the type of the result.

    In other words, the result undergoes integer promotion and gets the type int.
     
    For the second case, enumeration constants in C are just ints.
     
    XC8 is annoyingly pedantic with its warnings, but it's not incorrect.
    post edited by andersm - 2019/04/07 06:39:38
    #2
    crosland
    Super Member
    • Total Posts : 1622
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/07 09:43:31 (permalink)
    +3 (3)
    acharnley
    I've a few which don't make any sense. Take the following-


    uint8_t i = motion.frequency >= mpptMaxFrequency? mpptMaxFrequency : motion.frequency;


    Both motion.frequency and mpptMaxFrequency are cast as uint8_t. 

     
    There are no casts in that statement, so they are not being cast.
     
    If you mean they are declared as... then it would be better to create a small working example that shows the problem and post ALL of the code. God know how many times we need to repeat that to people.
     
    #3
    dan1138
    Super Member
    • Total Posts : 3229
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/07 19:40:58 (permalink)
    0
    crosland
    acharnley
    I've a few which don't make any sense. Take the following-

    uint8_t i = motion.frequency >= mpptMaxFrequency? mpptMaxFrequency : motion.frequency;

    Both motion.frequency and mpptMaxFrequency are cast as uint8_t.

    There are no casts in that statement, so they are not being cast.

    If you mean they are declared as... then it would be better to create a small working example that shows the problem and post ALL of the code. God knows how many times we need to repeat that to people.

    Could there be a hole in the C language specification for the trinary (?:) operator that causes integer promotion of the return value to occur?
    #4
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/07 19:43:55 (permalink)
    0
    ... as described in post#2? :)
     

    Nearly there...
    #5
    1and0
    Access is Denied
    • Total Posts : 9762
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/07 21:58:17 (permalink)
    +1 (1)
    crosland
    acharnley
    I've a few which don't make any sense. Take the following-

    uint8_t i = motion.frequency >= mpptMaxFrequency? mpptMaxFrequency : motion.frequency;

    Both motion.frequency and mpptMaxFrequency are cast as uint8_t. 

    There are no casts in that statement, so they are not being cast.
     
    If you mean they are declared as... then it would be better to create a small working example that shows the problem and post ALL of the code. God know how many times we need to repeat that to people.

    Either casting or declaring them as uint8_t will not rid the warning. Either the second or third operand needs to be or casted to uint16_t:

    uint8_t i = motion.frequency >= mpptMaxFrequency? (unsigned) mpptMaxFrequency : motion.frequency;

    which will promote convert both operands to unsigned int.
    post edited by 1and0 - 2019/04/07 22:22:57
    #6
    acharnley
    Super Member
    • Total Posts : 369
    • Reward points : 0
    • Joined: 2016/05/01 06:51:28
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/08 10:32:53 (permalink)
    0
    That didn't work, but the following did. I don't understand it, both mpptMaxFrequency and motion.frequency are uint8_t, the comparison is converting them?


    uint8_t i = (uint8_t) (motion.frequency >= mpptMaxFrequency? mpptMaxFrequency : motion.frequency);

    #7
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11340
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/04/08 11:16:52 (permalink)
    +1 (1)
    the comparison is converting them?

     
    Yes.  Most operators apply the usual arithmetic conversions.
    #8
    jjdiii
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2014/02/04 17:12:43
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/12 18:36:06 (permalink)
    0 (2)
    How about this:
     
    const uint8_t kCmdMask = 0x80;
    uint8_t cmdByte;
    uint8_t mSerialCommand;
    ....
     mSerialCommand = cmdByte & kCmdMask; //warning: (373) implicit signed to unsigned conversion

     
    It really shouldn't do that.
     
    James
    #9
    ric
    Super Member
    • Total Posts : 23859
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Another implicit signed to unsigned conversion warning 2019/07/12 18:56:14 (permalink)
    0
    Strange.
    XC8 v1.x all versions, and v2.x in C90 mode do that. C99 mode does not.
     
    Edit: Correction. v1.x only does it in versions 1.42 on. 1.41 and earlier don't do it.
     
     
    post edited by ric - 2019/07/12 22:28:30

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #10
    LdB_ECM
    Senior Member
    • Total Posts : 148
    • Reward points : 0
    • Joined: 2019/04/16 22:01:25
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/13 02:25:42 (permalink)
    0
    Yep that warning is wrong  ... I am guessing the const is causing the issue
     
    Does this get thru
    mSerialCommand = cmdByte & (uint8_t)kCmdMask;

    #11
    ric
    Super Member
    • Total Posts : 23859
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Another implicit signed to unsigned conversion warning 2019/07/13 02:53:49 (permalink)
    0
    LdB_ECM
    Yep that warning is wrong  ... I am guessing the const is causing the issue

    No. Same error without it.
     

    Does this get thru
    mSerialCommand = cmdByte & (uint8_t)kCmdMask;


    No. No difference.
     
    However, this DOES suppress the warning...
     
    mSerialCommand = (unsigned char)(cmdByte & kCmdMask);




    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #12
    1and0
    Access is Denied
    • Total Posts : 9762
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/13 11:12:13 (permalink)
    +2 (2)
    jjdiii
    How about this:
    const uint8_t kCmdMask = 0x80;
    uint8_t cmdByte;
    uint8_t mSerialCommand;
    ....
     mSerialCommand = cmdByte & kCmdMask; //warning: (373) implicit signed to unsigned conversion

    It really shouldn't do that.

    Yes, it should do that.  Both uint8_t operands are promoted to signed int type and the result of the & operation is a signed int, which is then assigned (converted) to an unsigned type.
    #13
    LdB_ECM
    Senior Member
    • Total Posts : 148
    • Reward points : 0
    • Joined: 2019/04/16 22:01:25
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/13 23:45:07 (permalink)
    +1 (1)
    Whilst the integer promotion to 16 bits always takes place - the C standard enforces this. Beyond that the compiler is allowed to optimize the calculation back down to 8 bits, it should be able to deduce that the sign will be the same.
     
    So it would be considered "poor form" for a compiler to throw a warning at that and few would.
    #14
    mlp
    boots too small
    • Total Posts : 805
    • Reward points : 0
    • Joined: 2012/09/10 15:12:07
    • Location: previously Microchip XC8 team
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/14 21:10:36 (permalink)
    0
    LdB_ECM
    So it would be considered "poor form" for a compiler to throw a warning at that and few would.

    The relevant Language Lawyer phrase is "Quality of Implementation".

    Mark (this opinion available for hire)
    #15
    1and0
    Access is Denied
    • Total Posts : 9762
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/14 21:15:50 (permalink)
    +1 (1)
    LdB_ECM
    Beyond that the compiler is allowed to optimize the calculation back down to 8 bits, it should be able to deduce that the sign will be the same.

    The compiler is allowed to optimize the expression to actually execute as an 8-bit operation. However, the compiler is not allowed to optimize out the implicit change of signedness caused by the integer promotion.
    #16
    ric
    Super Member
    • Total Posts : 23859
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Another implicit signed to unsigned conversion warning 2019/07/14 21:23:53 (permalink)
    0
    So, is the "PC" approach to avoid the warning just to cast the result back to unsigned, as I did in post#12?
    Casting both arguments doesn't help, as the promotion is done after that point.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #17
    1and0
    Access is Denied
    • Total Posts : 9762
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/14 21:36:01 (permalink)
    +1 (1)
    ric
    So, is the "PC" approach to avoid the warning just to cast the result back to unsigned, as I did in post#12?

    I think so -- I don't like it either, but it seems to be it is what it is. Because, otherwise, in some cases there is no way for the compiler to tell if the programmer is purposely relying on implicit promotion to happen, or if it is unintentional.
     
    Edit:
    ric
    Casting both arguments doesn't help, as the promotion is done after that point.

    Casting either or both operands to type unsigned int will help. ;)
     
     
    post edited by 1and0 - 2019/07/14 21:47:30
    #18
    LdB_ECM
    Senior Member
    • Total Posts : 148
    • Reward points : 0
    • Joined: 2019/04/16 22:01:25
    • Location: 0
    • Status: offline
    Re: Another implicit signed to unsigned conversion warning 2019/07/15 02:24:04 (permalink)
    0
    It's hard to know what to do with it because it's wrong, I have stated why (in spite of 1and0 comment).
    It doesn't warn with XC16, VS2017, VS2019, Keil DS5 or GCC 6,7 or 8 with wall on which didn't surprise me.
    The result is fully predictable and there is no chance of any error from the optimization so it is allowed to ignore the promotion.
     
    So personally I would just hack over it because to me it is junk but if you want to be anal then hit the C standards and see what is supposed to happen. The fact the all the other compilers ignore it tells me I am more likely right than wrong but I am not wasting time on it because at the end of the day it is perfectly safe.
    post edited by LdB_ECM - 2019/07/15 02:32:00
    #19
    NKurzman
    A Guy on the Net
    • Total Posts : 17846
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: Another implicit signed to unsigned conversion warning 2019/07/15 05:39:21 (permalink)
    +2 (2)
    I am not saying it is not a bug, but I would not be using 4 GCC compilers as proof( XC16 is GCC) GCC is not very standards compliant.
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5