奇怪的GCC short int转换警告

时间:2013-11-27 07:38:49

标签: c gcc implicit-conversion

我有一些C代码,它完全是这样的:

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

当我尝试使用GCC编译它时,我收到警告:

warning: conversion to 'short int' from 'int' may alter its value [-Wconversion]
  return a+b;
          ^

虽然没有明显的转换。两个操作数都很短,甚至返回值都很短。那么,有什么收获?

6 个答案:

答案 0 :(得分:6)

引用标准(§6.3.1.1¶2):

  

以下内容可用于intunsigned int的任何地方   使用:

     
      
  • 具有整数的整数类型(intunsigned int除外)的对象或表达式   转化排名小于或等于intunsigned int的排名。
  •   
  • 类型为_Boolintsigned intunsigned int的位字段。
  •   
     

如果int可以表示原始类型的所有值,则值为   转换为int;否则,它将转换为unsigned int。   这些被称为整数促销。所有其他类型   整数促销不变。

-Wconversion标志警告:

  

警告可能会改变值的隐式转换。这包括   真实与整数之间的转换,例如abs (x)xdouble;   签名和未签名之间的转换,例如unsigned ui = -1;和   转换为较小的类型,例如sqrtf (M_PI)。不要警告   显式广告,例如abs ((int) x)ui = (unsigned) -1   abs (2.0)中的转换不会更改值。警告   关于有符号和无符号整数之间的转换可以被禁用   使用-Wno-sign-conversion

答案 1 :(得分:6)

当你进行算术计算时,操作数受“通常的算术转换”(Acme's answer中引用的“整数促销”的超集)的影响 - 他打败了我,但我会继续发布无论如何:-))。这些扩展short int到普通int,所以:

a + b

计算与:

相同的结果
((int) a) + ((int) b)

return语句必须将此int缩小到short int,这就是gcc产生警告的地方。

答案 2 :(得分:3)

来自 C编程语言部分 2.7类型转换

  • 如果任一操作数为long double,请将另一个操作数转换为long double
  • 否则,如果任一操作数为double,则将另一个操作数转换为double
  • 否则,如果任一操作数为float,则将另一个操作数转换为float
  • 否则,请将charshort转换为int
  • 然后,如果任一操作数为long,则将另一个操作数转换为long

答案 3 :(得分:2)

当两个操作数均为short时,它们在算术运算中被隐式提升为int

答案 4 :(得分:0)

如果int可以表示原始类型的所有值,则该值将转换为int;否则,它将转换为unsigned int。这些被称为整数促销。所有其他类型都不会被整数促销更改。

参考以下帖子: Why must a short be converted to an int before arithmetic operations in C and C++?

答案 5 :(得分:-1)

GCC只会对生成临时值的操作执行这些隐式升级到int:

++i
i += 2

不会产生临时性。

i = j + 1

意愿。

以下代码:

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;

将以发布或调试模式提供以下输出: 2 4 4 4 2 4 2

指出虽然某些事情可能会抑制警告,但它们并没有实际阻止编译器升级到int。 所以要失去警告,停止生成临时工。