This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Integer conversion resulted in a change of sign.

Hi,

 

I develop DSP applications (C64x+) under DVSDK 4.00.00.22 (xdctools  3.16.03.36) for the Mistral EVM3530 board and I got the following  warning about an unsigned int (32 bits) but this should not appears because it is unsigned !


"main.c", line 462: warning #69-D: integer conversion resulted in a change of sign 

g_dwConfigStatus |= (1<<31);

 

I did a search on Ti forum about it but not find answer. What should I do to avoid this false warning?  Should remove all sign conversion checking if this option exist?

 

Thank you,

 

Daniel

 

 

  • Finally, I disabled this warning with a cast like that:

    g_dwConfigStatus |= (unsigned int)(1<<31); 

     

    but this seems to be a minor compiler bug under cgt6x 6.1.14 package toolbox.

     

    Daniel

  • Hmm.  1 is signed.  Shifting it left 31 bits puts it into the sign bit, creating a negative value.  ORing it with an unsigned variable causes an integer conversion.  Perhaps that's where the warning arises.

    You could also try 1U<<31, to use unsigned values throughout.

  • The compiler is correct to emit this warning.

    The unsuffixed integer constant "1" is of type "signed int"; the fact that it is immediately used in a bitwise operation is irrelevant.

    The C standard says [I quote from C99 because that's what I have handy; C89 say essentially the same thing]:

    Section 6.4.4.1 "Integer constants", paragraph 5:

    The type of an integer constant is the first of the corresponding list in which its value can be represented.  [I present only the relevant table entry, for unsuffixed decimal constants]

    • int
    • long int
    • long long int

    The expression 1<<31 overflows the size of signed "int", which is undefined behavior.  Undefined behavior means the program is illegal, and the compiler is free to do anything at all, such as crash.  The TI compiler allows the expression anyway, but emits a warning.

    The fix you really want is:

    g_dwConfigStatus |= (1u<<31);

  • Hi,

    Thank you pf and Archaeologist  for your explanations. I like your solution of using (1U<<31)  instead of a cast. When I posted this question I was surprise about why CGT6x compiler generate this warning thus the GCC do not when I compile like that:

    gcc -Wall test.c -o test

    But after your answer,  I removed the 'unsigned' on front of 'int' and GCC don't  generate any warning. So I realize now, this checking seems not be cover by the -Wall option of GCC, but Ti compilers does it correctly.

    Thank you.

    Daniel

  • GCC 4.4.2 has a warning for this circumstance, but it is not enabled unless you use "-Wconversion" or "-Wsign-conversion".

    Despite its name, "-Wall" does not turn on all warnings; in particular, it does not enable "-Wconversion"

     

  • I am getting a similar warning on the following:-

    typedef enum
    {
        E_VALUE1 = 0x83e70b13u,
        E_VALUE2 = 0x95a4f1e0u
    }e_values_t;
    typedef struct
    {
    uint32_t ELEMENT : 32u;
    }s_substruct1_t;
    pStructure->subStruct1.ELEMENT = E_VALUE1;

    Using Compiler Ti v5.1.5

    How do I get rid of that ?

  • Strictly speaking, in C89 you can't have enumeration constants that won't fit in the type "int", and those don't.  You can silence the warning by using the --gcc or --relaxed_ansi option, or you can disable that specific warning with the -pds69 option.

  • For anybody else in the future I've found that if I define it like this

    typedef struct
    {
      int32_t ELEMENT : 32u;
    }s_substruct1_t;

    The warning goes away.