未解决原始关闭原因
为什么这两个版本的代码不同?我的印象是无符号整数溢出在 C 中是明确定义的,如果你有 uint16_t a,b,那么 a-b
的结果类型为 uint16_t
。
#include <stdint.h>
uint32_t frobnicate1(uint32_t prevsum, uint16_t command, uint16_t response)
{
uint32_t error = command-response;
return prevsum + error;
}
uint32_t zoop1()
{
return frobnicate1(0, 30001, 30002);
}
uint32_t frobnicate2(uint32_t prevsum, uint16_t command, uint16_t response)
{
uint16_t error = command-response;
return prevsum + error;
}
uint32_t zoop2()
{
return frobnicate2(0, 30001, 30002);
}
但是 zoop1(
) 返回 -1(不是预期的!!!),而 zoop2()
返回 65535(预期)。
当我看到命令-响应
并且结果是 -1 模 65536 = 65535,并且应该具有类型 uint16_t
,我想知道为什么编译器在去uint32_t
时允许将 65535 提升为 -1。
(在 x86-64 gcc 和 clang -O2 -Wall
的 godbolt.org 上试用)
不一定。
C 对比 int 和无符号 int
窄的整数类型没有算术运算。如果
uint16_t
比无符号 int
窄(在大多数实现中都是这样),则在应用操作之前,任何类型 uint16_t
的操作数都将提升为 int
。
uint16_t
可能被定义为无符号短
;同样的事情发生在无符号短
型的操作数上,这些操作数通常被提升为 int
。