C中的整数算术溢出预防

问题描述

我认为以下代码可能会导致溢出,因为 a * 65535 大于 unsigned short int 所能容纳的范围,但结果似乎是正确的。

C 中是否有一些内置机制可以将中间算术结果存储在更大的数据类型中?或者它是一个意外?

unsigned char a = 30;
unsigned short int b = a * 65535 /100;
printf("%hu",b);

解决方法

之所以有效,是因为所有比 int 窄的类型都在 default promotion 之下。由于 unsigned charunsigned short 在您的平台上都小于 int,它们将被提升为 int,如果 int 包含 {,结果不会溢出{1}} 位或更多(这是 CHAR_BIT + 17 加号的结果) 22 位或更多(这是 a * 65535 加号中的位数)。但是,如果 30 * 65535 的位数较少,则会发生溢出并发生未定义的行为。如果 int 要么

默认提升允许更快地完成操作(因为大多数 CPU 使用其本机大小的值效果最佳)并且还可以防止发生一些幼稚的溢出。见