EDA365电子论坛网

标题: MDK常见报错(编译arm) [打印本页]

作者: pulbieup    时间: 2020-5-19 13:31
标题: MDK常见报错(编译arm)
工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.  x: A6 g7 T; ^! o7 i$ o
9 j* u* B% u/ Q8 G+ E
1.warning: #550-D: variable "d" was set but never used
5 H2 X3 e: v6 w  ]' C描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.
' _& n" O+ F, Q% j解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.3 Y* P1 V1 R& G) h( V7 U3 [

' Q' z6 S) R$ `/ W1 _" U9 x2.warning: #1-D: last line of file ends without a newline. y5 y( S: p2 ]4 C# f, e( y
描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.! o1 M, A: ]7 O
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.1 L: L8 r1 L% W: Y# M  o; u
. h0 m1 k9 e1 K* y5 [4 ~; x
3. warning: #111-D: statement is unreachable% W  ~$ F* L6 n# s" X/ {! w
描述:声明不可能到达.多出现在这种场合:
* f/ H  u9 \. n( s4 lint main(void); l+ C: R+ e/ M
{
1 X8 ]. G7 z. {3 b$ W...
6 G6 n% ]. V0 }: s* m( x) ^( ~, _0 O
while(1) //无限循环,这在不使用操作系统的程序中最常见: I8 j8 z! d5 a1 p. D3 Y
{
. E4 L6 X  y8 `% Z) A' v' e7 G...
: [0 H" `# `5 E5 [" `
1 y+ l4 R/ Y$ k3 ?7 w& ~+ h}
/ ~8 V! U" e9 B7 ?. K2 u: y
  J) w# ]& W+ ^% nreturn 0; //这句声明在正常情况下不可能执行到,编译器发出警告) F( z. I7 B7 |" N$ q
}6 C# F, e, V1 ]& r. ?, |. ^' {
; X" a: Z! d3 x8 {$ R1 z4 W0 _2 A
解决:不理会.
$ I. }8 V: H" A' \5 m! y8 z: N$ x! U; w. q; P% d$ B
4. warning: C3017W: data may be used before being set
- S; O$ Y5 {! I- }3 t6 e7 w! \描述:变量'data'在使用前没有明确的赋值.如:
+ E6 I0 v) r4 n' @, Luint8 i,data; //定义变量i和data,二者都没有明确赋值! y3 c6 ?- o( v

. E; A8 [: O  O  D3 j, Qfor ( i = 0; i < 8; i++) //变量'i'在语句中被赋值0
) Y, r) O' t/ s+ c, G8 }0 T{
$ }' g$ b; i" V/ N3 }: d* Mif ( IO1PIN & SO_CC2420 )
; a7 ]1 v4 {6 h8 q8 y0 Rdata |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告
& K9 U& z1 h7 ^1 r+ {" H/ c& U  \else( j. n3 v+ G2 m2 T8 T3 V
data &= ~0x01;
& L% Q/ R$ r# W1 D; C8 p0 C- l/ l}
. G; ?( n5 s) `" H" D/ {解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.
9 a5 t6 \  L- A+ w/ I! L6 ~6 F9 ^8 R3 s3 f& l- ~% G
5. warning: #177-D: variable "temp" was declared but never referenced2 E2 ?: k3 X$ x5 i) b
描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.- q+ H2 `) r: i: }
解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.
$ h* q* z) H9 a  m. A* b# S% y与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
( E' ^$ g; J/ ?# n
4 M) }# \1 l8 H) U+ j( \2 B; z6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"
1 G4 ^8 @% a! w# H) N+ H描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:- [; G1 b0 o* `$ n+ Y* o
int DealwithInspect2(uint32 test)
5 Z" \* ~0 p& Q: P{
% g+ y) g# J' [9 F% V# S/ Q% C...% h7 v  L; y# R
...
. E& L# w; h5 v, ^/ l...7 \+ C$ Y( J9 b4 x( z2 ]1 I# R
//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告" D* C. e( P" d; ]5 ^* d
}
. \) n! P1 V/ ]. U8 z: ?, A6 Q5 T" J* h0 I* _
7.
: P9 z- a) r" @
! B, L4 x; ?. K/ z9 z# C3 P1. error: #65: expected a ";"3 }1 W  A8 @- ]2 Y4 j
描述:缺少分号.大多是漏忘';'.3 v. n6 u; l' m3 D
解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.
1 Z, Z, ?% ]% w5 Y! n& E9 Z0 T. b4 }1 D0 v: F9 ]# O
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆$ a0 Z* B0 c  A- q! N- A# W
描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.
7 [( h& D. ~7 t# r' u$ F解决:仔细检查.h文件,将分号补上.
2 m; x5 s! q" C6 Y/ S9 S, c# V
( h9 J" k3 I9 t2 W8 M  \3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).
  @! \' U' Y5 M. J' t
7 I+ E$ [' |6 t5 |- B) i  E! K描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:/ b# s" A' ~* G2 u0 h1 N! u: z; J

& H# [# \5 D; m- O1 a1 }; Auint8 flagu=0;
" {- T0 c' M7 _5 ~0 U9 H: h( R, q- }" K7 k9 }
在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:: u6 f( t$ L; X) A* M1 c* O! X! p
$ U4 I2 u- R- C7 [7 I2 q
extern uint8 flagu=0;
4 l; k1 h$ p8 {5 V, U  x! A) m* G0 C5 r/ `$ c% [% g( b
然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
3 W1 f- B7 ?8 v: P) `
' q$ B; b( ?! h8 X- ?; Fextern uint8 flagu;
! r. ^2 V! E3 X( H* J
( F9 c9 D* F7 z解决办法:找到重复定义的变量,看情况修改一处.. G2 G# d2 ]% p) B8 e$ R( Q5 |0 m3 R
2 x- f  r4 ^& I2 W$ q( B; M: S
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)3 L1 A1 z1 E, X; }- F- V7 x
描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:$ q- s2 s4 a& r5 N( p1 c
void a(void) //函数a的实体: e' i$ t. u9 E  f
{, h* V9 ?  X3 O/ j
b(); //调用函数b: f9 L( m  |, j1 E$ Y$ V
}
' `# `2 }' e4 A* Y/ X; F% ^
3 L1 _3 R( X5 X) i$ i4 evoid b(void) //函数b的实体
8 D8 n& A& h; v. g  }( X8 ]/ h{
1 g! l. \' e/ P  b* f" ]& Y...6 z# N$ G. B; O" j- ]- C8 i0 r
}
; b1 s1 I$ E$ m这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.
- ?7 C# N( W# X, G3 Z解决方法:在函数a调用函数b之前,对函数b进行声明,如:
) R" O6 @$ x! ]: ^% j$ d, u  O& p/ t) Vvoid b(void); //对函数b进行声明
0 {# l( q) v1 n! {( G& |+ j- r* L. y) e
void a(void) //函数a的实体2 l* c/ ?& `2 R7 \. A) u7 K8 Y
{4 _* ]1 t: Y( H
b(); //调用函数b
3 J- f; W( \  u' i; _; E}
/ S$ W4 p0 B6 M1 H7 b( \, N1 i$ Y! c4 L' j  A0 H
void b(void) //函数b的实体2 z, E% ]+ [- F: C- Z5 K$ s
{$ ]) A" H" R; Z% e
...6 f1 e' c) e- W' @: x. N+ i* r
}
1 ]; L  J  R4 [# ~. k# l
作者: youOK    时间: 2020-5-19 14:50
MDK常见报错(编译arm)收藏了




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2