考虑以下程序(C99):
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void)
{
printf("Enter int in range %jd .. %jd:\n > ", INTMAX_MIN, INTMAX_MAX);
intmax_t i;
if (scanf("%jd", &i) == 1)
printf("Result: |%jd| = %jd\n", i, imaxabs(i));
}现在,据我了解,这包含了很容易触发的、未定义的行为,如下所示:
Enter int in range -9223372036854775808 .. 9223372036854775807:
> -9223372036854775808
Result: |-9223372036854775808| = -9223372036854775808问题:
(有几个相关的问题,但我没有找到一个回答上面的问题2,所以如果你建议重复,请确保它回答。)
发布于 2016-02-07 09:34:10
如果不能表示imaxabs的结果,那么如果使用两个补码,则行为是不确定的。
7.8.2.1 imaxabs函数
221)最负数的绝对值不能用两种补语来表示。
不作任何假设且总是被定义的检查是:
intmax_t i = ... ;
if( i < -INTMAX_MAX )
{
//handle error
}(如果使用补码或符号大小表示,则不能使用此if语句,因此编译器可能会发出无法到达的代码警告。代码本身仍然是定义的和有效的。)
发布于 2016-02-07 08:52:32
在两个补码系统上,获得最负值的绝对值确实是未定义的行为,因为绝对值将超出范围。编译器无法帮助您,因为UB是在运行时发生的。
防止这种情况的唯一方法是将输入与类型的最负值进行比较(在您显示的代码中是INTMAX_MIN)。
发布于 2016-02-07 22:38:14
因此,计算整数的绝对值会在一种情况下调用未定义的行为。事实上,虽然可以避免不明确的行为,但在一种情况下不可能给出正确的结果。
现在考虑整数乘以3:这里我们有一个更严重的问题。此操作在所有情况下调用2/3 3rds中未定义的行为!对于三分之二的int值x,要找到一个具有3x值的int是不可能的。这是一个比绝对值问题更严重的问题。
https://stackoverflow.com/questions/35251410
复制相似问题