【发布时间】:2014-11-15 19:52:24
【问题描述】:
我正在阅读有关此功能的信息:
int tadd_ok ( int x, int y ) {
int sum = x + y;
int negative_overflow = x < 0 && y < 0 && sum >= 0;
int positive_overflow = x >=0 && y >= 0 && sum < 0;
return !negative_overflow && !positive_overflow;
}
当我们将 TMin(即最小的 2 的补码)作为 y 的参数传递时,此函数存在问题。
在这种情况下,传入时 -y 将是 -y,即仍然是 TMin 第一个条件将显示我们对于 x 的值为负数的值为负溢出。
然后我读到实际上在这些情况下“x - y 不会溢出”。
我的理解是这个函数的问题是它没有考虑传递最小负数的极端情况。我可以看到它会返回一个negative_overflow 我看不到/不明白为什么这是错误的。
谁能帮我理解这个?
【问题讨论】:
-
这个函数的问题是它试图检测可能发生的溢出之后。这是错误的,因为已经发生了溢出的鼻守护进程。
-
@ouah:我猜正确的函数会在它发生之前尝试检测?我不知道这些方法有什么区别。除了这个错误的方法之外,为什么TMin被认为不会溢出?
-
问题在于,正如 ouah 所说,C 编译器试图把你搞砸而不是帮助你。许多 C 编译器不会使用 2s 补码算法让有符号整数溢出,然后让您检查结果和,而是假定 oevrflow 永远无法帮助优化溢出检查。有关详细信息,请参阅this question
-
@Cratylus
-INT_MIN不会换行,它会调用未定义的行为。有符号整数溢出调用未定义的行为。 -
是的,这是特定于 C 的,而且很麻烦。 C 标准来自并非每台计算机都使用 2s 补码算法的时代,因此有符号溢出被认为是未定义的行为。不幸的是,这并不意味着“未指定的行为”。当有符号溢出发生时,许多编译器会做一些无意义的事情,而不是总是以相同的方式溢出。
标签: c types integer integer-overflow integer-arithmetic