看完32 bit unsigned multiply on 64 bit causing undefined behavior? StackOverflow 上的问题,根据 C99 标准,我开始思考小型无符号类型的典型算术运算是否会导致未定义的行为。
例如,拿下面的代码:
#include <limits.h>
...
unsigned char x = UCHAR_MAX;
unsigned char y = x + 1;
x
变量被初始化为unsigned char
数据类型的最大值。下一行是问题所在:值 x + 1
大于 UCHAR_MAX
并且不能存储在 unsigned char
变量 y 中
。
我相信以下是实际发生的情况。
- 变量
x
首先提升为数据类型int
(6.3.1.1/2节),然后x + 1
被评估为数据类型int
。
假设有一个实现,其中 INT_MAX
和 UCHAR_MAX
相同——x + 1
会导致有符号整数溢出。这是否意味着递增变量 x
,尽管它是无符号整数类型,但可能会由于可能的有符号整数溢出而导致未定义的行为?
最佳答案
根据我对标准的阅读,使用 15 位 char
的实现可以合法地将 int
存储为 15 位大小并使用第二个 15 位用于存储符号和 14 位填充的字;在这种情况下,unsigned char
将保存 0 到 32,767 之间的值,而 int
将保存 -32,767 到 +32,767 之间的值。将 1 添加到 (unsigned char)32767
确实是未定义的行为。如果将 32,767 替换为 UCHAR_MAX
,则任何更大的 char
大小都可能出现类似的情况。
但是,与另一篇文章中提到的与无符号整数乘法相关的现实问题相比,这种情况不太可能发生。
关于无符号整数递增会导致未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27004694/