|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
工作后从单片机转成ARM,刚开始用ADS1.2编译器,用了一段时间,因为我接手的项目的老程序正是用ADS编译的,部门也大都在用.在学单片机的时候用的是keil c51编译器,ads和这个编译器在易用性上真是无法比较.后来渐渐知道keil已经被arm公司收购,现在keil MDK成为了arm官方编译器,所以决定重新投奔keil,利用平时的时间,将原程序重新用mdk编译.mdk的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.
8 u3 m5 a+ M; J* N
3 L! l* t$ u2 m/ d# V1.warning: #550-D: variable "d" was set but never used
3 t N* }$ d. i0 t, @# @描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.
6 ~1 o5 C" B2 ^1 L z' q& q解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
) q1 L; T0 {- e2 ~
# J5 Q1 }; w' u \/ k2.warning: #1-D: last line of file ends without a newline& W8 Q! H8 J: s. }0 R6 }
描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.1 i* J# {" }! O, n
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.; Q/ H9 L+ {: i5 N0 h; X8 k
: @ ^( M8 B6 @$ D" T4 N3. warning: #111-D: statement is unreachable6 a1 h5 R9 P# O/ u3 N' |% t6 }5 z' T
描述:声明不可能到达.多出现在这种场合:
9 d( T: \: P& Y Aint main(void)( r4 S+ ^5 ]( K* [; A+ ^0 g4 W- r" R
{
N# q$ O+ c* B...
$ e5 l5 w: L9 _4 R2 O. F; n* s( Z8 |+ V7 X7 o8 Q
while(1) //无限循环,这在不使用操作系统的程序中最常见' U, T' `; D) [3 [
{
% {, X8 ^% p. x...9 P5 ` C7 d+ b7 M
. Y3 A- G3 ` d: I8 T5 o& V. }}
/ x& K0 o2 ^: \% X
: B) _, g& ?7 F" Y& l5 w' ?( Lreturn 0; //这句声明在正常情况下不可能执行到,编译器发出警告
6 b0 G$ @- i, ?' m}
% s* ^, }( q( L/ t
! S; K; d2 @2 e- P7 E解决:不理会.
$ ?; L5 W0 E& L0 M# R0 H9 t5 L
% n7 m7 e5 `* J& B' ~9 r4. warning: C3017W: data may be used before being set+ u; }& d9 Q9 g& j* K7 B+ g
描述:变量'data'在使用前没有明确的赋值.如:. B" n1 U. X: V" Q# u& j
uint8 i,data; //定义变量i和data,二者都没有明确赋值
3 k. F5 Y% f3 p7 V2 D; u
' {" }* Q0 ~3 O, V |/ ?for ( i = 0; i < 8; i++) //变量'i'在语句中被赋值09 K8 r, i2 p5 ]
{
x: j3 f: J/ ~! ?3 J- s$ }if ( IO1PIN & SO_CC2420 ): D2 o8 `& h0 r# U8 S
data |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告
" ^- |9 r' d5 _+ I; c" w- helse8 e3 T4 p/ R( C; t G) V+ [1 Y6 p
data &= ~0x01;# Y2 E4 F; y# F3 b% X% C
}
* O# r# u. K8 p F) U4 P0 i解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.: R% |4 Q# K4 p- i2 F; ^! v
6 h3 N) M5 b' h m5 z
5. warning: #177-D: variable "temp" was declared but never referenced& H% H+ j& s* I; ?+ e4 p% m2 J
描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.
0 G7 n/ e# Q6 K f+ {$ k' W" U7 b; f0 p解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.
+ E s0 G z6 K* n5 n& ~6 I* [% D: k5 l与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
. G$ ~) K2 p3 Y7 s& A: Z" t. f: B2 z* Z# G3 a* m
6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"
" [% I6 r0 ^8 u0 _: y描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:% E5 T# q! b- @
int DealwithInspect2(uint32 test)
% H0 b$ k( d% P# H4 ? T6 E{
6 a5 q1 O# _" N5 k- G) j* b...# L8 t6 @6 N( ~( i9 w$ Z. g0 ]
...2 ? _& s! J! l* O
...) U1 ]# T$ Q3 m5 {
//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告
. d8 h( M% d: S1 A A}
) L# A1 [' K3 H
$ J( z/ y# b# y2 F; |; {3 s& n$ ~) ~7.
! T* U7 P$ ?, D; D9 s+ O
# f$ j" p# ?: z7 ^9 e. G! M1. error: #65: expected a ";"
* G: l4 D+ n0 b: O% h& ~描述:缺少分号.大多是漏忘';'.
# w1 L: V! J1 u# Z' _解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.& w4 s% G: V+ e$ Q: C0 |: l
' P$ e" u% w$ u, m4 J% Q
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆$ r' }5 u; w8 e& {
描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.
' j2 W. v; S' S7 Z! C/ ] D1 A2 Z解决:仔细检查.h文件,将分号补上.
0 D% J- B, b% r- {+ j
6 b% v) b7 L% Z ^3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).
/ {' S. X+ }2 A- o+ E( d$ Y
5 q! V1 q1 g7 }2 a描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:% P' l' [1 j p9 r* n
0 W& T% ^& W1 K1 d" kuint8 flagu=0;0 @4 X9 w2 @. B' b
5 T; i7 \. {% t1 p. M: ?- y在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:
; ? a$ l$ [) `& N- J6 d! U r2 p* x G# S u$ L% B7 u
extern uint8 flagu=0;
! S6 y0 A) M8 t1 M; f H
% t& I4 H+ E7 I- C% K然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:0 O$ m& C9 `5 I1 Q
8 ~( N; ?6 J# z" y$ Fextern uint8 flagu;: ]: o( t! g8 j3 _5 K3 {3 Z% ?
$ A% v6 u* K- M4 y' C$ Y
解决办法:找到重复定义的变量,看情况修改一处.
& X6 A! j1 A5 z* ?! g, s0 J' |- c0 j& S [+ ~
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)
1 R) b; Z; y5 O8 o G9 K G7 n描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:% b7 J% ~' [2 v4 h H2 e+ [% |
void a(void) //函数a的实体 k" T: Y! {6 S, m, n3 Z( H2 v: q
{8 y% O+ o, R; J9 h+ A
b(); //调用函数b" A; P% z, F2 i3 Q0 B9 |$ ~6 ~
}' v% `/ t6 r: Z, i, y
8 u. N2 G- h" a$ ]9 wvoid b(void) //函数b的实体
: T: N* J" N' R{
]% [4 A& y' t6 Z! L...7 F9 l4 A' W y
}
0 H4 F# X) [3 z) E( Q% W: O7 i这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.8 s2 c/ h4 P ]0 o! L8 ?
解决方法:在函数a调用函数b之前,对函数b进行声明,如:
' S- l! P ~) l- Z, dvoid b(void); //对函数b进行声明6 ]4 w+ O- m6 P6 `
2 b" p6 l7 K v0 E
void a(void) //函数a的实体- V$ ^% p/ S. C0 |5 l/ K
{1 O$ P( s# S2 G* n& |
b(); //调用函数b
( t: c3 V' G' h/ E$ q M6 K}) {5 \8 O" t' a" g: S
7 M4 k; W! G2 _! X- `' J# gvoid b(void) //函数b的实体
- q! t& A( N9 R1 i# K{7 V, f# u$ N2 b6 c+ s2 A
...
2 i" Q5 F0 P# g# G}" N$ t( a* ~# G, w! _4 q V+ ]
|
|