Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
奇怪的GCC短整数转换警告_C_Gcc_Implicit Conversion - Fatal编程技术网

奇怪的GCC短整数转换警告

奇怪的GCC短整数转换警告,c,gcc,implicit-conversion,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; ^ 虽然没有可见的转换。两个操作数都很短,甚至返回

我有一点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.3.1.1¨2):

在表达式中可以使用
int
无符号int
可用于:

  • 整数类型的对象或表达式(不包括
    int
    无符号int
    ),其整数 转换秩小于或等于
    int
    无符号int
    的秩
  • 类型为
    \u Bool
    int
    有符号int
    无符号int
    的位字段
如果
int
可以表示原始类型的所有值,则该值为 转换为
int
;否则,它将转换为
无符号int
。 这些被称为整数促销。所有其他类型都是 整数促销保持不变

旗帜警告:

警告可能改变值的隐式转换。这包括 实数和整数之间的转换,如
abs(x)
x
double
时; 有符号和无符号之间的转换,如
无符号ui=-1和
转换为较小的类型,如
sqrtf(M_-PI)
。不要警告任何人 显式强制转换,如
abs((int)x)
ui=(unsigned)-1,或者如果
值不会像在
abs(2.0)
中那样通过转换而改变。警告 关于可以禁用有符号整数和无符号整数之间的转换 通过使用
-Wno符号转换


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

当您进行算术计算时,操作数会进行“常规算术转换”(引用的“整数提升”的超集-他抢先告诉了我这一点,但我还是会继续发布:-))。它们将
short int
扩展为普通
int
,因此:

a + b
计算与以下相同的结果:

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

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

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

  • 如果任一操作数为长双精度
,则将另一个操作数转换为长双精度
  • 否则,如果任一操作数为
    double
    ,则将另一个操作数转换为
    double
  • 否则,如果任一操作数为
    浮点
    ,则将另一个操作数转换为
    浮点
  • 否则,将
    char
    short
    转换为
    int
  • 然后,如果其中一个操作数是
    long
    ,则将另一个操作数转换为
    long

  • 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;
    

    std::cout如果int可以表示原始类型的所有值,则该值将转换为int;否则,它将转换为无符号整数。这些称为整数。所有其他类型均不受整数升迁的影响

    请参阅以下帖子:

    i+=2
    表示
    i=i+2
    。右手边按照torek的回答进行整数升级
    ++i
    表示行为类似的
    i+=1
    。不,它没有经过那种提升。看看输出。。。我很清楚它们扩展到了什么。参见C116.5.16.2“形式为
    E1 op=E2
    的复合赋值与简单赋值表达式
    E1=E1 op(E2)
    ,不同之处在于左值
    E1
    只计算一次”。因此,
    i+=2
    i=i+2
    完全相同。我只是说它们是一样的,你这个傻瓜。如果你不识字,就不要回答。你说“它不会升职。”但它会;您的回答是,
    i+=2
    的行为与
    i=i+2
    不同(这是错误的,因为我们同意这两个是相同的)ISO C中的实际规则不同,导致堆栈溢出。请尽快阅读这一页。我不太清楚你的回答补充了什么,除了可能的重复之外,还没有补充什么。诚然,作为一个新来者,你还不能留下评论,但这是一个相当老的问题,它突然变得活跃起来。要为这样一个问题添加答案,您通常需要一些重要的新信息。