提问者:小点点

两种uint16_t类型的区别不应该也是uint16_t吗?[重复]


未解决原始关闭原因

为什么这两个版本的代码不同?我的印象是无符号整数溢出在 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 上试用)


共1个答案

匿名用户

不一定。

C 对比 int 和无符号 int 窄的整数类型没有算术运算。如果 uint16_t无符号 int 窄(在大多数实现中都是这样),则在应用操作之前,任何类型 uint16_t 的操作数都将提升为 int

uint16_t可能被定义为无符号短;同样的事情发生在无符号短型的操作数上,这些操作数通常被提升为 int