找回密码
 注册
关于网站域名变更的通知
查看: 339|回复: 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的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.
, D6 w9 I7 k' x  q6 l1 j. G$ ]" e$ c+ p5 N& V% u
1.warning: #550-D: variable "d" was set but never used
! Z7 }8 t/ {, g$ S% ?描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了./ M( @2 ?+ A* \5 E4 o; G: H
解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
$ ]. B+ I4 z" x' ~$ C9 j1 x+ v( j1 j. W7 }
2.warning: #1-D: last line of file ends without a newline
8 N# i4 q4 [3 F$ _, X5 |描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.% T. l3 z0 K6 [
解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.
, m4 T: I7 }* C8 L# f
0 a9 M6 J7 T/ h) _; a. f3. warning: #111-D: statement is unreachable8 e# y, ~. V" [8 K; Z
描述:声明不可能到达.多出现在这种场合:
0 n5 Z+ _# R$ T1 w% a- Jint main(void)
. ]7 u2 @5 |5 Q' Z- j{* T' ?! E9 [0 O' D  N" h  N9 D
.../ p* ^. t- r% L" O% r1 E( n0 ?
* [; J3 k  {7 Z# \
while(1) //无限循环,这在不使用操作系统的程序中最常见
  m( C6 I) T/ n* D; \! q{& L1 N4 U8 m- F7 y2 f' x  D: [
...: v* _3 K* u# P$ v# V$ q  U- @

; y& t, K2 Q: C+ q1 @) |}1 e# n! F: ^( }# a

/ i3 D: n5 V0 L/ i1 oreturn 0; //这句声明在正常情况下不可能执行到,编译器发出警告5 X2 V- j; v. s0 L
}/ C& c% y% Y0 q2 C
( d' C" e9 t& n4 \; U' Y" ^
解决:不理会." G/ U5 d3 N3 e

7 s% ^  X0 S8 p# D+ O6 v. F, E4. warning: C3017W: data may be used before being set" s- Z( S' z' u
描述:变量'data'在使用前没有明确的赋值.如:
" v0 c, |2 c0 Tuint8 i,data; //定义变量i和data,二者都没有明确赋值
$ ^3 }( j$ U3 q6 u  F4 z, R* j1 R( k
for ( i = 0; i < 8; i++) //变量'i'在语句中被赋值0
$ T% _5 \8 R3 h{' g- P0 A9 y; `- n5 B* D9 ?
if ( IO1PIN & SO_CC2420 )7 Y) P2 U5 Z2 j+ f
data |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告
) g! h: c% n& ?2 N) M. f/ T) welse# z% F6 g2 D+ d  O
data &= ~0x01;
9 v% I3 v2 H/ o. A# d}0 x# P5 `8 j( O: N/ a$ H
解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.% h# E& G. d0 ?
8 E; C# N& W. @6 x, I
5. warning: #177-D: variable "temp" was declared but never referenced4 h7 U% D* M/ W) x: ?. F. }
描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.
: g2 t" z# I' ^; F解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.
1 d  D5 H/ y; x5 A与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced! M- n  K: K0 p1 m; b* c( P

* O2 C& F' p5 T8 a! K1 v* {: O2 R6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"4 M! r  \: o* C7 A6 P, q! L. S
描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:$ o0 ]# T3 c4 L. T7 t3 E
int DealwithInspect2(uint32 test)# b* K' H6 m" h. S' G6 h# H$ D* ~
{$ J' X/ j, t( o% o* G
...% |$ j2 B. x7 X; N$ q% X
...0 d& i0 E3 s  j
...2 T) `, i6 r- @1 E) e: L
//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告
; d+ Z2 M: Y8 }: R9 J}
' c" w4 I7 y5 F: A% u! j# _( s6 s- a
7.) e+ ?* s4 a  `

6 U4 Q. A2 D# l% G3 H8 L2 j$ T1. error: #65: expected a ";"
8 C. H6 r# L* v; S描述:缺少分号.大多是漏忘';'., b! A# m* Y. V0 _' e; T6 B; N
解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.# c3 v- e# C; M. t, W' V
5 D- e- X0 b' d2 w8 n9 d. F
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆
6 U; d4 [$ f2 K; W+ g描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.* j! n+ Q' g: g  t7 d
解决:仔细检查.h文件,将分号补上.
0 B$ g' G: e( u# t& u7 F8 ], u) V0 R  ]. Q; s3 S; q: {
3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).# G* E! b" L9 W7 T# _
. `* E/ P9 g% e9 N9 U( _' {! A
描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:
% G' g8 U' L7 B0 }. w! A( `: ?3 W& z% Y2 W7 e- D6 }  y
uint8 flagu=0;
7 q: I( X; }& D2 l1 F& m# X/ s8 D
5 m0 A1 ~& @( X# G" t# v在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:" I+ a% S' ]9 [  w/ K
: r! w2 U( |; ~! [* G/ m
extern uint8 flagu=0;
0 C+ u: K; Y$ v' Y) H6 t# \) {" m, X
然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:/ R. m, g4 c9 {" @- J; S
5 B* Q- \( W0 x4 X( t7 W
extern uint8 flagu;0 o9 I) z5 W  j! j  S

5 b. f; q8 Q) z8 j解决办法:找到重复定义的变量,看情况修改一处.$ M: a- @5 n. s

, n& m! n+ T7 ]6 r4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)
2 T9 K2 `& T; t8 f" Z/ S8 G描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:
  j: F( N3 i& Q5 D4 rvoid a(void) //函数a的实体
% e4 h, e2 i7 D4 n) g6 [  R& g{- Y: E% W0 L1 q0 `) R* B& `, A
b(); //调用函数b
/ T* Y- h& y  j3 ?7 d}
" [9 k  |  P: W
5 }; ^, C/ w) Lvoid b(void) //函数b的实体, \% C9 L; ]& w" P, _
{
8 z7 [+ N1 P/ q& }% x...; e5 c! [( {4 h' ]& h% m
}( Y+ s9 J. t# G& w; q# e6 d- [$ M4 O1 J
这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.
. o! d3 P, i" n( B解决方法:在函数a调用函数b之前,对函数b进行声明,如:
4 y& X# Z( |6 b" z& `4 Vvoid b(void); //对函数b进行声明5 J6 p" B$ ~$ @/ m2 B2 _

7 v1 }  {5 @2 K0 W2 w% W( n  B# ^void a(void) //函数a的实体. Z9 b$ v( [5 I& o  w* |
{% {+ {" x4 z& P5 q: i  w
b(); //调用函数b' j, T! ?0 F/ p8 z
}" |+ M# L* k8 m# M4 u/ s3 d
6 C0 ], u4 L- V
void b(void) //函数b的实体
' v, s& J+ k3 o{
- |; ]# ]2 ~, ^+ m0 e* D  a...* F% D, j$ F' C* l) G% O4 B
}
! v/ a; d$ t0 p, [( w6 V5 R% n, A

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-28 21:27 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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