我有一些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;
^
虽然没有明显的转换。两个操作数都很短,甚至返回值都很短。那么,有什么收获?
答案 0 :(得分:6)
引用标准(§6.3.1.1¶2):
以下内容可用于
int
或unsigned int
的任何地方 使用:
- 具有整数的整数类型(
int
或unsigned int
除外)的对象或表达式 转化排名小于或等于int
和unsigned int
的排名。- 类型为
_Bool
,int
,signed int
或unsigned int
的位字段。如果
int
可以表示原始类型的所有值,则值为 转换为int
;否则,它将转换为unsigned int
。 这些被称为整数促销。所有其他类型 整数促销不变。
-Wconversion
标志警告:
警告可能会改变值的隐式转换。这包括 真实与整数之间的转换,例如
abs (x)
为x
时double
; 签名和未签名之间的转换,例如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
。char
和short
转换为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。 所以要失去警告,停止生成临时工。