GCC 警告此代码:
unsigned char i = 1;
unsigned char j = 2;
i += j;
说:
warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]
i += j;
^
似乎j
隐式转换为int
.
为什么添加相同类型的变量会发生隐式转换?
GCC 警告此代码:
unsigned char i = 1;
unsigned char j = 2;
i += j;
说:
warning: conversion to 'unsigned char' from 'int' may alter its value [-Wconversion]
i += j;
^
似乎j
隐式转换为int
.
为什么添加相同类型的变量会发生隐式转换?
以下是 C11 草案标准在第 5.1.2.3 节(第 15 页)中(几乎)对这种情况的说明:
例 2
在执行片段时
char c1, c2; /* ... */ c1 = c1 + c2;
“整数提升”要求抽象机将每个变量的值提升为
int
大小,然后将两个int
s 相加并截断总和。char
如果可以在没有 §5.1.2.3 Environment 15 ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 溢出的情况下添加两个s,或者使用溢出包装静默产生正确的结果,实际执行只需要产生相同的结果,可能会省略促销。
所以,它已经完成,因为标准要求它完成。如果您查看生成的代码,编译器很可能(非常)足够聪明,在实践中根本不进行转换。
C 要求整数提升,引用C11 N1570/6.3.1.1p2
可以在可以使用 int 或 unsigned int 的表达式中使用以下内容:
- 具有整数类型(int 或 unsigned int 除外)的对象或表达式,其整数转换等级小于或等于 int 和 unsigned int 的等级。
如果 int 可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为 int
因此,您的unsigned char
变量在这样的表达式中使用,因此被转换为int
,因为i += j
在功能上等同于i = i + j
.
如果您确定结果在 a 的范围内unsigned char
,那么只需在分配之前对加法的结果应用强制转换,如下所示:
i = (unsigned char)(i + j)