Strange GCC short int conversion warning

后端 未结 6 566
南笙
南笙 2021-01-18 15:41

I have a bit of C code, which goes exactly like this:

short int fun16(void){
    short int a = 2;
    short int b = 2;
    return a+b;
}

Wh

相关标签:
6条回答
  • 2021-01-18 16:26

    When both operands are short, they are implicitly promoted to int in arithmetic operations.

    0 讨论(0)
  • 2021-01-18 16:28

    GCC will only perform these implicit upscaling to int on operations which generate temporaries:

    ++i
    i += 2
    

    will not generate temporaries.

    i = j + 1
    

    will.

    The following code:

    std::cout << sizeof(i) << " "
    << sizeof(i + 1) << " " 
    << sizeof(i + static_cast<unsigned short>(1)) << " " 
    << sizeof(static_cast<unsigned short>(i) + static_cast<unsigned short>(1)) << " " 
    << sizeof(++i) << " " 
    << sizeof(i + 0x0F) << " " 
    << sizeof(i += 1) << std::endl;
    

    Will give the following output in either release or debug modes: 2 4 4 4 2 4 2

    Indicating that while some things may suppress the warning, they don't actually stop the compiler upscaling to int. So to lose the warning, stop the generation of temporaries.

    0 讨论(0)
  • 2021-01-18 16:36

    From The C Programming Language section 2.7 Type Conversion

    • If either operand is long double, convert the other to long double.
    • Otherwise, if either operand is double, convert the other to double.
    • Otherwise, if either operand is float, convert the other to float.
    • Otherwise, convert char and short to int.
    • Then, if either operand is long, convert the other to long.
    0 讨论(0)
  • 2021-01-18 16:39

    Quoting the standard (§6.3.1.1 ¶2):

    The following may be used in an expression wherever an int or unsigned int may be used:

    • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
    • A bit-field of type _Bool, int, signed int, or unsigned int.

    If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

    The -Wconversion flag warns about:

    Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like abs (x) when x is double; conversions between signed and unsigned, like unsigned ui = -1; and conversions to smaller types, like sqrtf (M_PI). Do not warn for explicit casts like abs ((int) x) and ui = (unsigned) -1, or if the value is not changed by the conversion like in abs (2.0). Warnings about conversions between signed and unsigned integers can be disabled by using -Wno-sign-conversion.

    0 讨论(0)
  • 2021-01-18 16:42

    When you do arithmetic computations, the operands are subject to "the usual arithmetic conversions" (a superset of the "integer promotions" quoted in Acme's answer—he beat me to this but I'll go ahead and post anyway :-) ). These widen short int to plain int, so:

    a + b
    

    computes the same result as:

    ((int) a) + ((int) b)
    

    The return statement must then narrow this int to a short int, and this is where gcc produces the warning.

    0 讨论(0)
  • 2021-01-18 16:43

    If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

    Refer the following post: Why must a short be converted to an int before arithmetic operations in C and C++?

    0 讨论(0)
提交回复
热议问题