什么,这个 C 语言大坑你没见过?
开发过程中,你是否会发出“基础不牢,地动山摇”的感慨,我相信,只要有经验的工程师,应该都有过。
uint16_t run_cnt, run_cnt_next;
voidfunction1()
{
do something ;
run_cnt++; // 自加,表示该函数已执行
}
intmain()
{
while(1)
{
function1();
if(run_cnt != run_cnt_next + 1) // 判断两个变量是否匹配
{
do error some thing
}
run_cnt_next++; // 这个位置也自加,表示这里已执行
}
}
甚至
短时间内运行不会有任何问题,除非 16 位溢出……
if(run_cnt != run_cnt_next + 1) // 判断两个变量是否匹配
{
do error some thing
}
比如上一次 run_cnt 为 0xFFFF 时(受位数限制,最大只能是这个),
run_cnt_next 为 0xFFFE,此次结果比较即使按 32 位比较,也是没有问题的,都是 0xFFFF。
那么为什么会导致上面的问题呢?这里涉及到两个 C 语言基础知识点,估计大家以前都了解过,但估计没有当回事。
1、常量默认为 int 型(但不一定是 32 bit ,和内核和编译器有关,上面的 +1 就是 int 型)
2、整型提升(详细可网上查找)
因为两边的结果类型不一致(+ 1 导致右边结果成了 int 类型),所以最终按 int 型处理。最终导致溢出时,结果判断失败。
我们可以通过汇编看出一些端倪:
我们可以看到 r0 + 1 之后,直接和 r1 比较,也就是说,结果可能超过 0xFFFF,导致出错。
if((uint16_t)run_cnt != (uint16_t)(run_cnt_next + 1)) // 强制转化为 16 位比较
{
do error some thing
}
我们可通过汇编发现,多了一条 UXTH 指令,用于把 16 位结果扩展成 32 位(从这里我们也可以得出结论,结果比较总是 32 bit 比较)。
这样写代码,美女同事乐开花
C++ 夺冠!2022 年度编程语言
模拟3万伏高压,MCU是否扛得住?
如何聪明地防止电源正负极接反?
关键词
代码
结果
流程
语言
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。