奇怪的IAREWSTM8编译错误

似曾相识   2010-7-16 14:22 楼主


下面代码是实现数码管上显示的简单代码,如果去掉case 7 //1处代码的话,编译通过,如果打开//1处代码的话,就出现严重警告错误,很简单的软件逻辑,不可思议为啥IAR EWSTM8会认为该处非法呢?弹出的错误提示信息如附件中的JPG文件所示


//停止状态下,数码管轮流显示 A->B->C->D->E->F->A
void StopStatus(void)
{
    switch(stop_step)
    {
        case 0: //工作状态下或者是设置参数状态下
            iStopStatusDelay = iDelayNow;
            break;
        case 1: //显示A
            stop_step = 2;
            
            SPI->DR = 0x7f;
            while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
            SPI->DR = 0x7f;
            while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
            GPIO_WriteLow(GPIOE, SCLK595);
            GPIO_WriteHigh(GPIOE, SCLK595);
            
            iStopStatusDelay = iDelayNow;
            break;
        case 2: //等待 A 显示0.1秒后显示 B
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 3;
            
                SPI->DR = 0xfe;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
                SPI->DR = 0xfe;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
   
                GPIO_WriteLow(GPIOE, SCLK595);
                GPIO_WriteHigh(GPIOE, SCLK595);
               
                iStopStatusDelay = iDelayNow;
            }
            break;
        case 3: //等待 B 显示0.1秒后显示 C
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 4;
            
                SPI->DR = 0xfd;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
                SPI->DR = 0xfd;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
   
                GPIO_WriteLow(GPIOE, SCLK595);
                GPIO_WriteHigh(GPIOE, SCLK595);
               
                iStopStatusDelay = iDelayNow;
            }
            break;
        case 4: //等待 C 显示0.1秒后显示 D
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 5;
            
                SPI->DR = 0xfb;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
                SPI->DR = 0xfb;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
   
                GPIO_WriteLow(GPIOE, SCLK595);
                GPIO_WriteHigh(GPIOE, SCLK595);
               
                iStopStatusDelay = iDelayNow;
            }
            break;
        case 5: //等待 D 显示0.1秒后显示 E
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 6;
            
                SPI->DR = 0xf7;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
                SPI->DR = 0xf7;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
   
                GPIO_WriteLow(GPIOE, SCLK595);
                GPIO_WriteHigh(GPIOE, SCLK595);
               
                iStopStatusDelay = iDelayNow;
            }
            break;
        case 6: //等待 E 显示0.1秒后显示 F
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 7;
            
                SPI->DR = 0xef;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
                SPI->DR = 0xef;
                while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
   
                GPIO_WriteLow(GPIOE, SCLK595);
                GPIO_WriteHigh(GPIOE, SCLK595);
               
                iStopStatusDelay = iDelayNow;
            }
            break;
        case 7: //等待 F 显示0.1秒后显示 A
            if(Calculate_10ms_Based_TimerDelay(iStopStatusDelay) >= 10)
            {
                stop_step = 1; //1处
            }
            break;
    }
}

IARCUOWU.JPG (13.05 KB)

回复评论 (10)

吼吼,不奇怪了,静默同学提示我加上default分支
default:  break;
结果还真通过了
不过通过这个问题,反应出来另一个奇怪的问题:
在IAR EWSTM8里,switch()语句是不允许缺少default语句的,IAR可能考虑到怕你漏掉一个case值的时候出现问题,但是在标准C里并没有规定在switch()语句必须有default分支,从这点上说IAR是不兼容标准C的,另外:

即使缺少个default分支,IAR也没必要蹦出这么个吓人的错误提示吧,从该提示里根本看不出跟default有什么关系呀?个人觉得可以给个警告,但是应允许编译通过,软件出现错误是软件的事儿,回头会很容易跟踪到的,建议IAR改下该处问题的提示内容,至少跟switch default 啥的关联下,让用户大概知道个范围呀

另外奇怪的是,即使不加上default语句的情况下,屏蔽掉1处的代码,编译还是能通过的,这些到底怎么解释呢?
点赞  2010-7-16 15:09
                                 我的switch case里没有default这句,一样没有任何问题。
点赞  2010-7-18 10:57
                                 问题是我添上default之后就通过了,IAR弹出的这个错误太吓人,很多人都会被搞蒙
点赞  2010-7-18 13:27
                                 LZ的建议很好,不过导致错误的原因太多,让编译器太过具体,也是太理想化了
点赞  2010-7-18 22:04
                                 但是在IAR EWSTM32里我没见过这样的夸张错误提示
点赞  2010-7-18 23:39
同感啊。。这几天也是被IAR的报错给弄懵了
各种错误,哪种都让人摸不着头脑- -
点赞  2010-7-19 10:37
                                 只能说明编译器太不人性化了,没有给出正确的指引,找问题的难度相应也提高了很多
点赞  2010-7-19 16:17
                                 在IAR EWSTM32里确实没发现过这么多离奇的错误提示,相信IAR EWSTM8随着版本的提升会逐渐的越来越人性化
点赞  2010-7-19 18:45
                                 好像不是这个问题,我测试当case语句到8个以后就出楼主的错误
点赞  2010-9-3 20:52
                                 IAR EWSTM8 还是有很大进步空间的
点赞  2010-9-3 22:03
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复