This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

__inline and change of sign warning

Hi all,

I would like to discover why the compiler issues warning #68 (integer conversion resulted in a change of sign) for the code below. It is issued only for -O3, "Optimize for Time" enabled and when the function is inlined (__inline keyword).

I have tried to cast anything which could be implicitly converted to int back to uint, but no chance to get rid of this warning.

armcc.exe V4.0.0.524

static __inline uint8_t IsDecDigit(char c)
{
    return (   (c >= '0')
            && (c <= '9'));
}

...

static void UseIt(void)
{
    char *name;
    ...
    /* Initialize the name to something useful */
    ...
    if (   (IsDecDigit(name[3])) /* <- warning issued for this expression */
        && (IsDecDigit(name[4]))
        && (IsDecDigit(name[5]))
        && (IsDecDigit(name[6]))
    {
        ...
    }
}

Thanks for responses.

Regards Pavel

Parents
  • As I see it now, I would rather agree it's just a compiler bug as mentioned somewhere above...
    Anyway, there is complete and completely useless example you want ;)
    Use the compiler settings mentioned earlier.

    #include <stdint.h>
    #include <lpc23xx.h>
    
    /*
     * Set to nonzero to remove warnings ;)
     */
    #define REMOVE_WARNINGS 0
    
    static char *random_data = (char *)0x40000000;
    
    
    /*
     * Remove __inline and warnings disappear
     */
    
    
    static __inline int IsDecDigit(char c)
    {
        return (int)((   (c >= (char)'0')
                      && (c <= (char)'9')) ? 1 : 0);
    }
    
    
    static __inline int IsSet(uint32_t flags, uint8_t pos)
    {
        return (int)((int)(flags & (1ul << pos)) ? 1 : 0);
    }
    
    
    static DoSomething(uint8_t what)
    {
        FIO0CLR = (1ul << what);
    }
    
    
    static DoSomethingElse(uint8_t what)
    {
        FIO1SET = (1ul << what);
    }
    
    
    int main(void)
    {
        char     *name  = random_data;
        uint32_t  flags = 0;
    
    #if REMOVE_WARNINGS /* Not sure why..., maybe compiler chooses different optimization when there is inline asm? */
        __asm("nop");
    #endif
    
        for (;;)
        {
            if (IsDecDigit(name[0]))
            {
                DoSomething(1);
                flags |= (1ul << 0);
            }
    
            if (   IsDecDigit(name[1])   /* warning:  #68-D: integer conversion resulted in a change of sign */
                && IsDecDigit(name[2]))
            {
                DoSomething(2);
                flags |= ((1ul << 1) | (1ul << 2));
            }
    
            if (IsSet(flags, 3))
            {
                DoSomethingElse(3);
            }
    
            if (   IsSet(flags, 4)       /* warning:  #68-D: integer conversion resulted in a change of sign */
                && IsSet(flags, 5))
            {
                DoSomethingElse(5);
                flags |= 0xf;
            }
        }
    
    /*    return 0;*/
    }
    

Reply
  • As I see it now, I would rather agree it's just a compiler bug as mentioned somewhere above...
    Anyway, there is complete and completely useless example you want ;)
    Use the compiler settings mentioned earlier.

    #include <stdint.h>
    #include <lpc23xx.h>
    
    /*
     * Set to nonzero to remove warnings ;)
     */
    #define REMOVE_WARNINGS 0
    
    static char *random_data = (char *)0x40000000;
    
    
    /*
     * Remove __inline and warnings disappear
     */
    
    
    static __inline int IsDecDigit(char c)
    {
        return (int)((   (c >= (char)'0')
                      && (c <= (char)'9')) ? 1 : 0);
    }
    
    
    static __inline int IsSet(uint32_t flags, uint8_t pos)
    {
        return (int)((int)(flags & (1ul << pos)) ? 1 : 0);
    }
    
    
    static DoSomething(uint8_t what)
    {
        FIO0CLR = (1ul << what);
    }
    
    
    static DoSomethingElse(uint8_t what)
    {
        FIO1SET = (1ul << what);
    }
    
    
    int main(void)
    {
        char     *name  = random_data;
        uint32_t  flags = 0;
    
    #if REMOVE_WARNINGS /* Not sure why..., maybe compiler chooses different optimization when there is inline asm? */
        __asm("nop");
    #endif
    
        for (;;)
        {
            if (IsDecDigit(name[0]))
            {
                DoSomething(1);
                flags |= (1ul << 0);
            }
    
            if (   IsDecDigit(name[1])   /* warning:  #68-D: integer conversion resulted in a change of sign */
                && IsDecDigit(name[2]))
            {
                DoSomething(2);
                flags |= ((1ul << 1) | (1ul << 2));
            }
    
            if (IsSet(flags, 3))
            {
                DoSomethingElse(3);
            }
    
            if (   IsSet(flags, 4)       /* warning:  #68-D: integer conversion resulted in a change of sign */
                && IsSet(flags, 5))
            {
                DoSomethingElse(5);
                flags |= 0xf;
            }
        }
    
    /*    return 0;*/
    }
    

Children
No data