作者:GorgonMeducer 傻孩子
首发:裸机思维
Arm Compiler 5,也就是大家熟悉的armcc,距离官方2017年最后一次更新已经过去3年多了。实际上官方早在2016年发布Arm Compiler 5.06u3的时候就已经通过各种渠道对外界喊话——“我要是再更新armcc,我就卖了我自己”,结果2017年,5.06u6不期而至,孙正义爸爸的钱还是“真香”的——这里也许有些许戏虐的成分在里面,但armcc接近软件生命周期的终点是不争的事实:
- armcc 真的太老了!也许用户用起来感觉还挺趁手,但实际上已经是“屎山”一座了;
今天,我们就给大家展示一个Arm Compiler 5.06u6 “最终绝对不改版6” 中一个惊为天人的BUG。
1、准备好一个新鲜的 Arm Compiler 5.06u6。如果不确定自己的armcc是不是这一版本,可以打开MDK的help->About,如果你是日常的armcc玩家,应该可以看到类似如下的信息(是的,就是这个 V5.06 update 6)
2、随便建立一个可以编译和调试的例子工程,并将优化等级设置为 -Otime -O3。具体方法如图所示:
3、插入以下的测试代码
#include <stdio.h>
void break_tesk(uint_fast8_t chValue)
{
printf("entering switch...\r\n");
switch (chValue >> 4) {
case 0:
printf("do something...");
break;
case 1:
printf("do something...");
break;
case 2:
do {
printf("\tInput is 0x%02x", chValue);
if ((chValue & 0x0F) < 7) {
break;
}
printf("You will not see this");
} while(0);
printf("\tYou should see this ");
break;
default:
printf("it is a default");
break;
}
printf("\r\nleave switch...\r\n ");
}
4、在超级循环中调用该函数,并传入参数0x22,例如:
void main(void)
{
...
break_test(0x22);
...
}
5、编译并运行,观察输出:
分析代码不难发现,针对输入0x22,我们会从do{}while(0); 结构中跳出,并继续执行后续的代码,也就是打印“\tYou should see this ”,因此一个可能的输出结果是:
entering switch...
Input is 0x22 You should see this
leave switch...
然而,我们实际观测到的是:
6、修改优化等级为 -O3 -Osize(如图所示,只要去掉 Optimize for time前面的勾选就行了),编译并运行,观察输出:
可以发现,代码中 do{}while() 结构内部的break被错误的当作了switch的break,从而跳过了 do{}while() 结构后面的代码。通过修改优化等级到-O3 -Osize或者是-O2 -Otime都可以避开这一问题。那么,这一问题是否严重呢?我觉得我要手动@一下所有使用protoThread和所有使用switch状态机的童鞋们,就问你们慌不慌。
【玄学说法】“状态机好像容易跑飞……我也不知道是怎么回事,代码逻辑没问题啊?”;“高优先级下生成的代码不可靠!”;“switch里面的break和for以及do while的break究竟怎么用?我好方”;“我遇到一个bug,你来看看”,“我什么都没改啊,换个优化等级就对了……”,
【实际情况】编译器bug没的洗……但是bug就是bug,不要怀疑人生,不要怀疑自己所学的语法,发现bug有条件的话请及时报告。
【后记】
其实按道理说,这种bug应该非常明显,不至于被留到最后一个版本,仔细想想,至少有以下几种可能:
- 这是 Arm Compiler 5.06u6 从 5.06u5 升级过程中引入的——正可谓拔出萝卜带出泥。可惜实际情况并不是这样的。有兴趣的朋友们可以去测试下老版本;
- 大部分用户对C语法掌握情况不佳,基本处于模棱两可的状况;遇到类似情况不会用一个严谨的态度首先去确认正确的语法及行为;在坚持正确语法的情况下分析问题,从而判断出这是一个编译器错误;
- 大部分用户不敢用最高的-O3 -Otime优化;
- 大部分开最高优化的用户关心的主要是代码尺寸,从而恰好避开了这个问题;
- 大部分用户没空去纠结这一问题;
- 大部分用户遇到这类问题后,默默的选了-O0……
- 大部分用户相信玄学……
- 少部分牛人发现问题后懒得报告……
“大人,时代变了”
最后,欢迎大家尽早投入到Arm Compiler 6、IAR、GCC的怀抱……
专栏推荐文章
【编译器玄学研究报告】第一期——位域和volatile
大白话说嵌入式安全(1)
大白话说嵌入式安全(2)
什么是嵌入式系统(上)
什么是嵌入式系统(中)
什么是嵌入式(下)—— “重力”和“沉淀”
如果你喜欢我的思维,欢迎订阅裸机思维
版权归裸机思维(傻孩子图书工作室旗下公众号)所有,
所有内容原创,严禁任何形式的转载。