【发布时间】:2017-12-28 22:44:32
【问题描述】:
作为问题"Is unsigned integer subtraction defined behavior?" 的扩展,我对以下行为感到困惑。
在下面的代码中,请注意 A = 50 和 B = 100 存储为无符号 16 位整数和减法 A - B = -50 = 65486 (mod 2^16 - 1)。如果我将减法的结果存储在D(一个无符号的 16 位整数)中,然后计算D > 4000,我得到true,因为65486 > 4000. 这是有道理的。
如果我放弃存储A - B 并直接评估A - B > 4000,我会得到错误。这似乎不一致。这是预期的结果吗?为什么?这总是正确的行为还是我处于“未定义行为”的境地。
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t A = 50;
uint16_t B = 100;
uint16_t D = A - B; // D = 65486
printf("D = %u\n", D);
int R = D > 4000; // R = 1 (true)
printf("R = %d\n", R);
int S = A - B > 4000; // S = 0 (false)
printf("S = %d\n", S);
return 0;
}
顺便说一句,这种行为似乎与this question 的代码中的行为相矛盾,这进一步让我感到困惑。如果我将上面的uint16_t 更改为uint32_t,我会得到
D = 4294967246
R = 1
S = 1
这对我来说似乎是正确的。
更新:似乎最好的详细答案是 uint16_t 被提升为 int(int 在我的系统上是 32 位),所以 A - B > 4000 完成了 已签名 算术。而当我切换到 uint32_t 时,没有执行任何提升(已经是 32 位宽),所以 A - B > 4000 是使用 unsigned 算术完成的。这样就可以解释了。
附:我知道人们想第一个回答,但仅仅说“整数提升”并不是一个有用的答案。
【问题讨论】:
-
整数促销。
-
哪些整数促销?如果 A 和 B 提升为 32 位无符号整数,则 A - B > 4000 应该为真。如果将它们提升为带符号的整数,那就更没有意义了。具体有哪些促销活动?
-
这取决于:
int您的系统是 32 位还是 16 位?你会得到不同的答案。 -
如果
int/unsigned== 16,uint32_t未被提升 - 仍然是uint32_t。如果int/unsigned== 32,则uint32_t提升为unsigned。如果int/unsigned== 64,则uint32_t提升为int。
标签: c++ c undefined-behavior