【发布时间】:2015-01-16 06:05:47
【问题描述】:
在阅读了 StackOverflow 上的32 bit unsigned multiply on 64 bit causing undefined behavior? 问题后,我开始思考对于小型无符号类型的典型算术运算是否会导致根据 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,尽管它是无符号整数类型,但可能会由于可能的有符号整数溢出而导致未定义的行为?
【问题讨论】:
-
如果
sizeof(unsigned char) == sizeof(int),则适用第一种情况。 -
@chux 如果
int可以代表价值,为什么促销不会发生? -
我会回顾“6.3.1.8 通常的算术转换”这似乎首先适用“否则,如果具有无符号整数类型的操作数的等级大于或等于另一个类型的等级操作数,然后将带符号整数类型的操作数转换为无符号整数类型的操作数的类型。"这出现在“否则,如果带符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值......”规则。
-
我坐得更正了。如果
INT_MAX >= UCHAR_MAX,unsigned char x将按照“常规算术转换”转换为int。 -
假设这就是为什么代码应该使用
unsigned char y = x + 1u。
标签: c language-lawyer c99 undefined-behavior