You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何uint16_t减法需显式转换?运算结果类型问询

无符号16位整数减法的类型提升问题

问题背景

若所有变量均为uint16_t,为何需对减法结果进行显式强制转换才能得到正确结果?

我使用16位自由运行定时器实现微秒级延时,发现使用16-bit无符号整数时,必须进行显式强制转换,否则while循环会无限执行。但使用uint32_t变量时无此问题。硬件架构为Cortex-M,编译器为GCC 10.3.1

核心问题:当sizeof(操作数) < sizeof(int)时,减法运算的结果是否为int类型?

最小复现测试用例

#include <stdio.h>
#include <stdint.h>

static void
delay_until_not_working(uint16_t start_time, uint16_t delay_time) {
    uint16_t curr_time = start_time;
    
    /* 无限循环——即使是无符号整数 */
    while ((curr_time - start_time) < delay_time) {
        printf("Start: %5d, Curr: %5d, delay: %5d\r\n", (int)start_time, (int)curr_time, (int)delay_time);
        curr_time++;
    }
}

static void
delay_until_working(uint16_t start_time, uint16_t delay_time) {
    uint16_t curr_time = start_time;
    
    /* 添加了uint16_t强制转换 */
    while ((uint16_t)(curr_time - start_time) < delay_time) {
        printf("Start: %5d, Curr: %5d, delay: %5d\r\n", (int)start_time, (int)curr_time, (int)delay_time);
        curr_time++;
    }
}

int
main() {
    printf("Delay until working..\r\n");
    delay_until_working(65530, 200);
    printf("Delay until endless loop..\r\n");
    delay_until_not_working(65530, 200);
    return 0;
}

问题解答

是的,当操作数的尺寸小于sizeof(int)时,会触发C语言的整数提升规则,减法运算的结果会是int类型,这就是导致循环异常的根本原因:

  • 在delay_until_not_working函数中,curr_time和start_time都是uint16_t,在Cortex-M这类32位系统中,uint16_t的尺寸(2字节)小于int的尺寸(4字节),所以这两个变量会先被提升为int类型再执行减法。
  • 当curr_time从65530递增到65535后,再加1会触发无符号整数溢出,变为0。此时计算curr_time - start_time等价于(int)0 - (int)65530,结果是-65530(一个负的int值)。
  • 随后这个负值和被提升为int的delay_time(200)比较,-65530 < 200永远为真,因此循环陷入无限执行。

而添加显式强制转换后能正常工作的原因:

  • (uint16_t)(curr_time - start_time)会把提升后的int结果强制转回uint16_t,按照无符号整数的规则,-65530转换后等价于2^16 - 65530 = 6。
  • 随着curr_time继续递增,这个差值会从6开始逐步增大,当达到200时,循环条件不满足,正常退出。

关于uint32_t无问题的原因:
在32位系统中,uint32_t的尺寸等于int的尺寸,不会触发向int的整数提升,减法运算结果保持uint32_t类型,溢出后的差值会按无符号整数的模运算规则计算,因此循环能正确判断退出条件。


内容的提问来源于stack exchange,提问作者unalignedmemoryaccess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 05:54:39