无符号整数递增会导致未定义的行为吗?

标签 c language-lawyer c99 undefined-behavior

看完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_MAXUCHAR_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/

相关文章:

c - 如何使用 printf() 格式化字符串以获得相同的输出长度

c - 在 C89 中重写多维 VLA

C99 可变长度数组维基百科示例

c - 当 main 没有参数定义时,argc 和 argv 是否仍然存在于堆栈中?

c - 用 fread 读取一个空文件

c++ - 具有依赖字段的结构体的聚合初始化

c++ - 为什么 Same_as 概念检查类型相等性两次?

C: 将 int 转换为 size_t

c++ - 使用 Chebyshev 距离探索矩阵

c++ - 推导指南、initializer_list 和类型推导过程