|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.; W9 a4 U; ], @( i/ z
$ y) Z% y3 L0 i1 V8 }3 h& m
1.warning: #550-D: variable "d" was set but never used6 t$ K# x( k" W, d. H% `* j
描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了., i, _* ^; n5 W% _9 }1 d+ C* C) `1 u
解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
% o+ Q! M- ^, k9 V8 t* q7 n7 G* [. T& V2 e6 }% N2 Q0 a6 k$ Z4 ?6 \
2.warning: #1-D: last line of file ends without a newline
; v/ H+ Z5 c) ?描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.! |9 W4 \# j7 L% ] y* l
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.
0 e2 m- {- o+ B3 q2 w5 L
5 B$ ~% C6 v0 t) o+ l3. warning: #111-D: statement is unreachable
, b& G' p, z# J5 ~/ Z4 J描述:声明不可能到达.多出现在这种场合:3 f' {6 c7 `, l1 I
int main(void)
+ d7 s( b( _: ^: h2 k) P{
6 u7 S6 V w. e! x! Q5 [$ o7 |- k" X...& y% ^- I: U7 P+ Q+ m
" V4 M( H* E3 z
while(1) //无限循环,这在不使用操作系统的程序中最常见
+ u6 G/ N M; [5 ?: {! q% F{ v4 p) U4 l8 k6 M$ C0 b
...0 B# g* n1 a$ W# f
C# v' C! C* m4 i9 r}
. e8 Z }7 S3 k% d, v( P4 r. @/ X- k. N: ]8 q% h
return 0; //这句声明在正常情况下不可能执行到,编译器发出警告7 K/ @: D, @, R, @. i. O4 \- x- _2 o
}
% C3 f* C/ e( H- ]+ N" K \
+ r6 d$ ^4 L) F解决:不理会.
) A- ^: Y9 N5 r( D& A
' g1 n5 F, X( r4. warning: C3017W: data may be used before being set! B5 N3 z; q7 l2 E5 a; ~9 s
描述:变量'data'在使用前没有明确的赋值.如:/ X! U( ~1 i7 N# z% P
uint8 i,data; //定义变量i和data,二者都没有明确赋值0 C" ]: I$ [: Z
9 V9 y2 l9 Z/ V9 h: N' Sfor ( i = 0; i < 8; i++) //变量'i'在语句中被赋值0
( m$ L. U& g* E9 O q{- | g& x- b& M! k# D
if ( IO1PIN & SO_CC2420 )
# M: e }" u: F' t7 V) s$ ndata |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告
$ H, Q0 L3 X# C, kelse* G( R |, C; H N
data &= ~0x01;7 w+ ~/ S% k3 Y& n0 j* V1 }6 F
}
% N& N& w9 s" s$ y8 I! ^ n解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.
% n" C# ?9 o) y' P( S1 h0 u* c6 ^) l6 i" P
5. warning: #177-D: variable "temp" was declared but never referenced: s. }: _3 _- O
描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.
6 F% J3 j* j5 c' E8 B, d解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.% ~; U- `$ D$ x2 `' `1 W7 f
与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
2 L( I8 f- e* C7 W1 x1 a4 y/ [! d7 }7 @/ N {
6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2": I8 M6 w" T+ }
描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:6 a: m( I6 g3 m" V5 I
int DealwithInspect2(uint32 test)
: M& s# Z+ q9 w, R{ Z- d0 q, j0 G" v, `
...8 @- E" l( F( w, w5 F
...+ J+ H- a9 \5 I/ Y8 t
... f8 E7 [3 f) s# C3 M( A- `# o
//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告9 {$ i2 i% q- l; p+ r' D1 [% `
}/ y6 k7 x1 V8 z- O- B
7 l/ }: t( v. j+ [! f7.- [7 e0 h: C4 h) Z1 V& n
# `1 t, E* ] w" ^9 f7 ^1. error: #65: expected a ";"
) @$ E" {# I4 {7 q描述:缺少分号.大多是漏忘';'.
8 s3 q9 s. I& f2 n5 Y7 Y9 ~: }解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.
, E' E& z, b6 f1 c0 t# Q3 D
+ J V& R9 O8 j: F# B0 l4 B" G2 n2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆
7 l& s8 I6 N" J. c& ~9 U描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.! l2 D; o# s. c0 T
解决:仔细检查.h文件,将分号补上.
( l) M% S" W9 R9 z) U6 f: s0 Q' b( O: E. Q
3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).
. |3 O2 m3 a+ s! v* d) `$ D$ x0 t5 p" x* Q
描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu: {; V+ E3 y; @' y0 \( Z# E6 `
' N1 m- c/ _9 v% `+ z
uint8 flagu=0;: W+ D) ^7 T6 L1 E) Y9 a& y3 r$ j
+ x! z x1 z$ [& W9 v- J- W在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:/ V2 i. t. t" Z$ Z: o; {
, b/ q7 X! R. F+ B+ h" \* I6 _! Bextern uint8 flagu=0; u6 P% o; t6 @4 b! a* v5 U# ^
/ y- T# j) C, S! `& g
然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
7 K1 f6 E; S5 u6 B: x: S: ^. Q6 P) w: H' a8 h6 p
extern uint8 flagu;
& H- w0 Z! Y8 f- v: h: F
; t+ ]- q g0 P解决办法:找到重复定义的变量,看情况修改一处.
# h5 {& T4 i6 ~ v# ]5 K2 Q9 z- x' C
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)! _' C u6 q; J
描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:
; M+ C0 D/ I1 @. t% v5 v# t+ D# Uvoid a(void) //函数a的实体, r; K0 R- J$ d% [
{2 v3 h2 X- u, E) c( E! d
b(); //调用函数b/ Y8 o: s9 c# v1 t
}, ~' e$ ~- M+ S8 F" Z5 z
: i$ n- t5 f1 {8 g+ L% e5 {void b(void) //函数b的实体* [2 t% v$ P; I7 W m o
{$ t& ?! @- _+ U
...5 n2 Q) t: b0 q' E; n/ E6 a
}
0 @1 W3 t, i# q- W+ [: R这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.- b+ o/ z9 M& k6 _7 F# P, |2 z
解决方法:在函数a调用函数b之前,对函数b进行声明,如:7 M1 T+ w6 c/ k
void b(void); //对函数b进行声明; p$ Y0 u/ Z' z. S
0 F: l" |5 g+ g( n+ J$ G; ~void a(void) //函数a的实体0 @* ~ f- [0 { z0 _" f
{
' L1 m: F+ ?* Q9 O1 t' \$ wb(); //调用函数b3 V7 ?( e8 ]$ O0 h
}) |. N: ]( V. |/ ~
- ?0 [2 ^# v* Q+ q$ ^+ @
void b(void) //函数b的实体( Q' L+ a& g1 d5 a: ^, ^$ u8 }
{0 ^' r. i$ F' m: @! i9 |
...
2 U6 y" Q# x8 `0 j% O}9 h7 e- v3 C6 C( {/ x
|
|