找回密码
 注册
关于网站域名变更的通知
查看: 346|回复: 1
打印 上一主题 下一主题

MDK常见报错(编译arm)

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-5-19 13:31 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.
$ V0 B" `* `' @; [6 R
- ?* {: \  N# }6 O1 B" Y1.warning: #550-D: variable "d" was set but never used
( C* B- N% T9 Y$ ]描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.5 Z, z$ [8 s) a% d
解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
3 T6 M' c; Y  u& i
2 _, R, o( M# @  w2.warning: #1-D: last line of file ends without a newline- b5 H  b1 t, h/ q
描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.- H7 c* h0 c7 X$ G4 b, Z. l0 H
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.
; S( F# b# \# n/ H, G9 B
0 Z6 S1 H# n; G, Z6 K* c3. warning: #111-D: statement is unreachable
* ~+ P7 [/ }" V. ]6 U3 E3 t3 J1 z; ^描述:声明不可能到达.多出现在这种场合:
! B1 w5 K$ M8 f# j& u1 I1 lint main(void)4 [$ A0 c! K: b8 t; k9 R
{
; {1 m7 o) d8 R$ K( M...6 u' _, i! S5 l

- {. \/ Y$ N. j. nwhile(1) //无限循环,这在不使用操作系统的程序中最常见
. |2 k+ _7 `" f4 V4 e$ W7 A( O# ]( C{
2 o1 Z2 q( D! J; N7 A9 A2 |...) I2 \- C  ~+ ]3 k/ e- }

0 \5 v# n5 B$ a5 |}
) q/ z: D* u4 X: n0 W+ ~! ]* m1 A' y( @3 v& }0 w
return 0; //这句声明在正常情况下不可能执行到,编译器发出警告8 {1 J# `) W, f( G
}
" Z  u) R, H6 t2 {' C! f. O! Q8 ^8 O6 P0 _3 I; B' t* }
解决:不理会./ e3 ~8 q% z+ W0 {# P2 D  l# \

8 {) }$ a. x$ c4 s5 B4. warning: C3017W: data may be used before being set
2 \# A; W  M6 E描述:变量'data'在使用前没有明确的赋值.如:
  F' I% H3 d; G9 Quint8 i,data; //定义变量i和data,二者都没有明确赋值7 C4 [$ W3 @& h. s3 I; Q, V

9 S. X( p  u1 e7 kfor ( i = 0; i < 8; i++) //变量'i'在语句中被赋值0- o3 ~% P" j$ x, `% ^
{) _) P3 Y. w# L# n/ i
if ( IO1PIN & SO_CC2420 )
/ ]& l; b- W( r+ j% Z6 Z- H) Wdata |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告6 W8 n& _0 \; W: w9 Y
else
, O: E) n5 Z6 o5 mdata &= ~0x01;
3 h8 I/ Q0 X8 l/ @- }}
7 M' U( Y2 j0 l. P解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.
. R8 a( a- I2 r- \! Y7 G
  l( T% Y- ~/ T2 _5. warning: #177-D: variable "temp" was declared but never referenced
! j" ~) }+ E; t+ k7 E) K描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.2 ^5 Y/ U8 t$ S$ I; j* R
解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.: y' D' W( c, u! [  X, J5 @7 l
与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
- X" r& `% u1 \/ ^. \3 x
% [) |" Q$ q; Z6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"9 j) E7 x& r2 a
描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:; u( m. y" I7 I. Y, I5 [
int DealwithInspect2(uint32 test)+ ~8 d/ ?5 X  t: A5 A
{' ^* q/ J) d. m# K" x
...# n* x( u1 [+ K' ^# O
...2 U# f' q' O" ]
...
- N$ {. d6 ^- Q) y//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告7 c) \7 }4 g, I6 n) v
}2 q+ Z0 u! p/ J$ l

. M0 {& H( o: p0 s) W" A7.! k( a8 L8 A" q0 U3 _& ?! o0 P
( [: m6 x' F5 l* C
1. error: #65: expected a ";"
. s9 w( i5 Q- P# i: f. L描述:缺少分号.大多是漏忘';'.6 n0 Y8 Z+ Z9 W" o; S% g! A/ g+ {
解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.
& W8 c/ o6 q6 e# w. T# h' S( ^6 h* I& M" V
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆
" x7 P) V! o8 M" l描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.8 f. q$ S: o6 c. h% }1 O0 G# @- j5 e! b
解决:仔细检查.h文件,将分号补上.% ]1 ~0 o, t% J4 v) g" I

. g; _0 o" R0 U" _3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).4 x* u% b9 a" W0 O' [
( @: V1 @! [  _8 V/ V' {/ @
描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:9 j8 j* B) M4 d4 e6 F
7 I2 y7 g' l7 L' `! j
uint8 flagu=0;5 y# ~' V' e9 d9 x) n$ j2 I2 `4 j

) _, ?1 T3 V, P/ }5 ?7 l: R/ {在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:
0 g7 s+ L% L/ H' g6 Y2 ^' a8 e$ [6 T- h: ^
extern uint8 flagu=0;, M* g: k% y+ F# L. U! M1 G

6 ?8 I5 e7 |: G" [- M! \0 `+ C  }6 _然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
. F7 `7 @  v8 ~$ n9 D3 B( q8 g# Q& Y8 n. Z
extern uint8 flagu;
% y4 j( T  E8 S/ y  j* J( C1 R7 z# d0 D! a6 Q$ w
解决办法:找到重复定义的变量,看情况修改一处.
* ~1 y* D5 F. T) q$ O
' b8 x/ r% s# m+ w' F7 m/ D+ p- n4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)' U0 V$ v. B) z/ }
描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:
8 U; k( v) d9 {: b$ i2 h4 Kvoid a(void) //函数a的实体
% ]6 y6 @2 Z- D# c6 u{
* A% m* u( ^; ^# s6 Q, t8 b/ Xb(); //调用函数b; H0 R! g' P0 _3 e0 }
}: @- _0 j! j8 j3 ?+ t
) q% P, Z+ ]/ @, |( n
void b(void) //函数b的实体' J: j, r; V0 k3 j* @% t1 G8 N
{
1 [% n' @& t0 q# D2 C4 y' i' Z7 u...
1 k6 {& q2 N: f  G}4 x! F8 e; Q! A9 M" b; w. M8 C0 `
这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.& ^( x4 A, h/ v6 O: v. |
解决方法:在函数a调用函数b之前,对函数b进行声明,如:0 `, y# Q4 {$ f: U4 ?4 d
void b(void); //对函数b进行声明$ B3 ^. U8 |& }& w: O3 v0 s' d

/ i5 _6 P* b3 y( y6 lvoid a(void) //函数a的实体
1 M) E4 S0 E) F: @{
( x; w! W0 I2 ?3 m4 R. h1 `4 jb(); //调用函数b
0 f6 Y/ G' R1 ^9 m8 O}
" J1 Q* \# c+ F
8 c" ?$ q& ]* e2 w1 p$ u9 s& Y9 Evoid b(void) //函数b的实体
; |, u  e" Q: l0 m6 f* k{+ E2 K# f; ^4 b# [& T2 U
...
) ]: }) Y9 _: X}
* B4 Z- M9 {; d& O; H9 z* r& t

该用户从未签到

2#
发表于 2020-5-19 14:50 | 只看该作者
MDK常见报错(编译arm)收藏了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-26 04:46 , Processed in 0.156250 second(s), 24 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表