首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C=a+b与隐式转换

C=a+b与隐式转换
EN

Stack Overflow用户
提问于 2015-07-27 12:01:42
回答 3查看 1.6K关注 0票数 18

使用我的编译器,c为54464 (16位截断),d为10176。但是对于gccc是120000,d是600000。

真正的行为是什么?行为不明确吗?还是我的编译器是假的?

代码语言:javascript
运行
复制
unsigned short a = 60000;
unsigned short b = 60000;
unsigned long c = a + b;
unsigned long d = a * 10;

是否有办法对这些案件发出警报?

对以下事项发出警告:

代码语言:javascript
运行
复制
void foo(unsigned long a);
foo(a+b);

但并没有警告:

代码语言:javascript
运行
复制
unsigned long c = a + b
EN

Stack Overflow用户

回答已采纳

发布于 2015-07-27 12:16:40

首先,您应该知道,在C中,标准类型对于标准整数类型没有特定的精度(可表示值的数目)。它只需要对每种类型的最小精度。这些结果导致了以下典型的位大小标准允许更复杂的表示:

  • char:8位
  • short:16位
  • int:16 (!)比特
  • long:32位
  • long long (自C99):64位

注意:在limits.h中给出了实现的实际限制(这意味着一定的精度)。

第二,执行操作的类型取决于操作数的类型,而不是赋值左侧的类型(因为赋值也只是表达式)。为此,上面给出的类型按转换等级排序。秩小于int的操作数首先被转换为int。对于其他操作数,级别较小的操作数转换为另一个操作数的类型。这些是常用算术变换

您的实现似乎使用了与unsigned short相同大小的16位unsigned short,因此ab被转换为unsigned int,操作以16位执行。对于unsigned,该操作执行模块65536 (2到16的幂)--这称为环绕(这是而不是签名类型所需的!)。然后将结果转换为unsigned long并分配给变量。

对于gcc来说,我认为这是为PC或32位CPU编译的。为此,(unsigned) int通常有32位,而(unsigned) long至少有32位(必需)。因此,这些操作没有包装。

注意:对于PC,操作数被转换为int,而不是unsigned int。这是因为int已经可以表示unsigned short的所有值;不需要unsigned int。这可能导致意外的(实际上:实现定义的)行为,如果操作的结果溢出signed int

如果需要定义大小的类型,请参见stdint.h (自C99)中的uint16_tuint32_t。这些是具有适合您的实现的适当大小的类型的typedef

您还可以强制转换一个操作数(不是整个表达式!)对结果的类型:

代码语言:javascript
运行
复制
unsigned long c = (unsigned long)a + b;

或者,使用已知大小的类型:

代码语言:javascript
运行
复制
#include <stdint.h>
...
uint16_t a = 60000, b = 60000;
uint32_t c = (uint32_t)a + b;

注意,由于转换规则,转换一个操作数就足够了。

更新(感谢@chux):

上面所示的铸造没有问题。但是,如果a的转换级别大于类型广播,则可能会将其值截断为较小的类型。虽然可以很容易地避免这种情况,因为所有类型都是在编译时已知的(静态类型),另一种方法是用所需类型中的一个进行乘法:

代码语言:javascript
运行
复制
unsigned long c = ((unsigned long)1U * a) + b

这样,就可以使用cast或a (或b)中给出的类型的更大级别。任何合理的编译器都会消除乘法运算。

另一种方法,即使不知道目标类型名称,也可以使用typeof() gcc扩展来完成:

代码语言:javascript
运行
复制
unsigned long c;

... many lines of code

c = ((typeof(c))1U * a) + b
票数 16
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31652572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档