|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.2 t; L& U5 d& i9 B
" {+ [- e( ^0 e- n2 u) c5 d
1.warning: #550-D: variable "d" was set but never used* f G. H# c) C r
描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.
: C. E7 ^- q$ p3 E. \1 O解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
7 M& c+ ]; t6 n! b" v9 k& S8 D7 C0 [( v
2.warning: #1-D: last line of file ends without a newline
: t) }! M+ T6 g; i* L描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.' f$ \3 P: F0 K7 {& I4 A6 Y- B0 ]% F2 Q
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行., O3 ~" ^0 e' [ }# N/ b
: E9 ]; Q; t+ R/ c8 [# ~9 j3. warning: #111-D: statement is unreachable
4 L" ^) }+ X# k, v描述:声明不可能到达.多出现在这种场合:
A0 p/ y8 w& Z( L( l1 Z( vint main(void)
* ]& u% i* J r( X{
, |( q) q6 C$ n& T/ h1 B% w: e: M...$ {$ P$ A, n. D4 o8 C
3 l4 ?: s/ E' Q. R8 c$ Q: V
while(1) //无限循环,这在不使用操作系统的程序中最常见8 Q# Q( V- g1 P: \
{
0 }' Y% ?8 V4 B9 p- U: f.... [& J: w f- @5 _
( T- o0 L* ?6 A0 Z) n
} m/ ]1 b4 w6 `
3 |$ g+ Q, z/ v$ y
return 0; //这句声明在正常情况下不可能执行到,编译器发出警告
( S& _/ B9 P4 {7 B: j W}
$ z0 n$ J7 |& U) }
; L' N1 }+ U# ~+ k2 w: x) u解决:不理会.# o# N: p7 h; p
; ^) X2 W, t6 r, H7 a8 U0 P4. warning: C3017W: data may be used before being set
* O/ N! `3 ^- i) K( f2 }描述:变量'data'在使用前没有明确的赋值.如:
1 L" ~% c. f) {' |4 O8 d+ p) {uint8 i,data; //定义变量i和data,二者都没有明确赋值, `- T& u4 S/ U8 C" Y' L6 N, }
) Z0 z8 D! T2 t/ R. b9 ^
for ( i = 0; i < 8; i++) //变量'i'在语句中被赋值0- b# J" s2 `" G% u
{1 S- U0 q0 w v3 \: f- Y0 |
if ( IO1PIN & SO_CC2420 ); K8 S7 `) Z; W7 q5 i$ P/ @
data |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告$ w% V9 K! P6 N6 s
else
: Q* i" n' {& O5 B+ X/ [data &= ~0x01;
2 t: M% Q3 x( @1 d& O}& I9 W! N8 j( D' [9 V q0 }3 ~3 ~
解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.
+ x* M, l/ A, i6 u5 ?4 |5 i) t! U! I6 Q. f5 [: T+ a
5. warning: #177-D: variable "temp" was declared but never referenced
: ^ D6 B7 `. y1 ]: I, [描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.* {# G, D5 R2 S9 U. p n1 N/ I
解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.
" e/ i ]3 C8 W1 u4 D( j与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
- }& J- S# w8 e$ I: ]6 C1 Y. y2 B- v, c
6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"
0 _) _0 ]( G3 p: x: l% S描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:2 g7 c! [: u3 f) A3 G* R
int DealwithInspect2(uint32 test)
8 c7 x$ l! J7 ]% D* F{' ?1 L- m2 m4 K* u% \, N
...5 S% R% Y4 N+ ^" e) f' w# L
...
0 z9 j* R. n& x$ f @0 m' q...
. g4 \; w. v: T//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告8 D, h, \+ `9 w- S5 Z' L3 s) v
}
2 T: ]1 ^' j; h! v2 g3 @% P6 h% O4 E1 A
7.
& E4 K5 u+ x8 q* C/ g, x6 R6 ]2 k9 t8 b+ S) }- [
1. error: #65: expected a ";"
/ y+ N" d9 D2 @. D- D& B描述:缺少分号.大多是漏忘';'.
# J3 U' ~: Z$ d1 H0 p8 M解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.* ]. v4 L" \/ e" L" J! S ]/ x
% h4 P' \8 Z5 n
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆% ]1 x- L2 c' n G. j3 j
描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.4 B; a/ T% ?- u9 a
解决:仔细检查.h文件,将分号补上.
8 a3 S6 q/ N3 k- y
T6 W$ [$ b4 X5 H3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).: p% a+ d8 a) b5 |! d$ D" d# F
# ^0 r, ^7 U2 o4 j g* P `1 v
描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:" k5 L8 L* N# _7 l! Z# b" i
( u9 T1 m' J' {6 h' Z) @# v/ P" O
uint8 flagu=0;
. w# t5 e' y, v {
" V0 n4 [& f: F2 Y% e在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:
0 s: u8 u$ |5 M1 h' ~
p. f* d: W6 }5 A- wextern uint8 flagu=0;2 N& n B* V( H$ C
- Z5 M' I2 F b
然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
- c! ?" `! E4 X4 Q, b v9 t% i. ?0 z, e j9 J2 E. H
extern uint8 flagu;
, `" |, f1 q) g9 B$ ?4 @
, D0 X R5 Z" o8 `5 D9 @' m4 Z解决办法:找到重复定义的变量,看情况修改一处.
. ^ d; e; j" a$ X/ |+ Z4 F. a/ @# F- z" q0 ]' Z: D
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)9 e4 o: |% b1 s5 A8 H
描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:. Z$ b+ J: P8 `, ?
void a(void) //函数a的实体# K% w" a5 z$ M# b6 _! a$ J) u
{& k9 k, l+ H( \1 J& N
b(); //调用函数b0 m" i/ ^& _/ r, g1 C
}) x2 i& M4 q5 Z8 _- E6 b% B# b& @+ B
# {+ @0 w& A6 g) q$ R' cvoid b(void) //函数b的实体5 R6 L; c$ M( F, `( a
{3 r ]7 h$ |0 b0 g( S( N J
...
) {3 S" \; y |, h, @}. P1 F) R& Q7 j! D
这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.
' M# y4 Z; Q& b! X$ W解决方法:在函数a调用函数b之前,对函数b进行声明,如:
$ t8 T) j/ d" _, |3 k8 t/ Nvoid b(void); //对函数b进行声明2 r! P& o# P- y% T: s
4 O7 b# F& X; m) J _+ O' |. J
void a(void) //函数a的实体
0 w6 g5 [5 W8 {% I& B* f{
/ }4 c8 K$ |+ k1 f+ \b(); //调用函数b
$ u1 x" }8 r( K0 A}# M- @0 m: M& Y: r$ V0 A1 i3 ~
! X/ Y- T. s& c1 D; J
void b(void) //函数b的实体
) \2 _ P i! F) g' v{1 Y! P- ]9 E1 M1 a1 U! N
...& C' }" K" h, Z, v
}
3 Q( {7 |$ d# N1 x- i( o+ ` |
|