# V1070. Signed value is converted to an unsigned one with subsequent expansion to a larger type in ternary operator.

This diagnostic rule applies to ternary operators whose second and third operands are integer types with different type modifiers - signed and unsigned. The warning is triggered when the ternary operator's result is saved as a larger unsigned type. If such conversion takes place, negative values become positive.

Take a look at the example below:

    long long foo(signed int a, unsigned int b, bool c)
    {
      return c ? a : b;
    }

The compiler will process the code above according to C++ conversion rules. The ternary operator's second and third operands contain different types and the unsigned operand's size is no less than the signed one's - this is why the compiler will convert them to an unsigned type.

Thus, a signed variable with a negative value (for example, -1) will be cast to an unsigned type. In case of the 32-bit 'int' type, the resulting value is '0xFFFFFFFF'. Then this result will be converted to a larger integer type (the 64-bit 'long long' type). However, by then, the value will have lost its negative sign and will remain a positive number.

The problem also arises in cases when a ternary operator's result is converted to a larger-sized unsigned type:

    unsigned long long f(signed int i, unsigned int ui, bool b)
    {
      return b ? i : ui;
    }

If the 'i' variable has a negative value (for example, -1), the ternary operator's result is '0xFFFFFFFF'. Then it will be cast to a larger unsigned type and the value will be '0x00000000FFFFFFFF'. Most likely, the developer expected to see '0xFFFFFFFFFFFFFFFF' as the result.

This diagnostic is classified as:

CWE-681 CERT-INT32-C