找回密码
 注册
关于网站域名变更的通知
查看: 348|回复: 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的优点就没必要说了,在这里把平时遇到的编译器给出的警告和错误信息给出详解,希望给初学者一点帮助,发现错误,需要补充的欢迎留言.
4 c6 V* Z& |! i  L( }- L  w: F# B$ m  P8 ~; O: ~! ^8 K$ Q
1.warning: #550-D: variable "d" was set but never used6 {9 f6 R' d5 p! b. G
描述:变量'd'定义但从未使用,或者是,虽然这个变量你使用了,但编译器认为变量d所在的语句没有意义,编译器把它优化了.
$ }* j/ h- Y/ c  R$ C9 I: _# q解决:仔细衡量所定义的变量d是否有用,若是认定变量d所在语句有意义,那么尝试用volatile关键字修饰变量d,若是真的没有用,那么删除掉以释放可能的内存.
! m4 {0 {4 o+ U4 t5 `2 u# q( K% ^1 @
2.warning: #1-D: last line of file ends without a newline
1 v& s9 a1 S2 ?7 o描述:文件最后一行不是新的一行.编译器要求程序文件的最后一行必须是空行,想了半天没想通为什么要这样.
: o  d3 ^# K9 V& T1 b$ F5 o# Q解决:可以不理会.若是觉得出现警告不爽,那么在出现警告的文件的最后一行敲个回车,空出一行.
/ o4 z( t* R3 [7 t. e7 g/ n
4 }8 Q4 e% l8 I6 W7 K7 W% V3. warning: #111-D: statement is unreachable
- R4 j$ Z& P& b* u描述:声明不可能到达.多出现在这种场合:
# P, {8 b! S9 n' Sint main(void)$ b9 Q# A( b0 w9 x8 n
{
$ c# i! m8 n' S6 X0 i; Q...0 O& |" u7 i7 U+ c8 x

/ A7 F9 w/ r" L& Owhile(1) //无限循环,这在不使用操作系统的程序中最常见
" ?4 ?+ j# K9 G$ k. Q{
' ~% Y. K8 u( ?5 e1 {, C- ]' F...
' N8 }6 G6 g3 H3 n9 P; s& H" a5 [5 p8 R% h
}
1 j; D; ^" J8 ~+ n" \* j- r) c# X$ X4 _- C. y9 g9 _9 S' \: G( ~) J3 ?2 s
return 0; //这句声明在正常情况下不可能执行到,编译器发出警告
5 Z  [5 ]4 v8 i: ^0 ]" c, a}
/ ^8 D) p! s9 M: n
$ ^7 O% c) a+ @2 E6 k2 c+ i解决:不理会.: J5 v/ A5 L- I- }: Y! A/ X. A
5 H) r5 Q# ]2 Y2 a+ q" \
4. warning: C3017W: data may be used before being set
6 t! r$ v2 X+ K5 D! f9 d+ J6 Y8 `2 {描述:变量'data'在使用前没有明确的赋值.如:
6 _$ a- o  a0 r2 ?* ouint8 i,data; //定义变量i和data,二者都没有明确赋值) {  _( K8 x  I, j  ]! B

. ?1 X, Q1 r9 P) vfor ( i = 0; i < 8; i++) //变量'i'在语句中被赋值08 O* ^8 r9 N8 k1 w1 I
{+ U, M0 k& `, p# L4 A. ]2 m
if ( IO1PIN & SO_CC2420 )- l0 \8 K, t3 @( s7 r: S
data |= 0x01; //变量'data'在使用前没有明确赋值,编译器发出警告5 O' x5 ^  D( Z7 b# q
else$ ~' k" _' e  ?, S+ _
data &= ~0x01;
  _2 U( C1 k! q1 v$ f9 K4 [, U+ w}$ o% ?$ u; O' x8 N" t: D
解决:应仔细衡量该变量的初始值是否为0,若是,可以不理会这个警告,因为MDK编译器在程序执行前,会将使用到的数据区初始化为0,但若是该变量的初始值不应该是0,忽略这个警告可能会引起致命错误.这个警告应引起足够重视.应养成变量赋初值的习惯,好在有编译器给把关.8 C  {' T: s& X/ W

, z0 s, Y/ W) {( V  Q5. warning: #177-D: variable "temp" was declared but never referenced
0 D, A- |9 m! u/ y, y  t2 s* m描述:变量'temp'进行了声明但没有引用.多出现在声明了一个变量,但却没有使用它,它和warning: #550-D: variable "temp" was set but never used不同之处在于temp从没有使用过.
" y- U5 z9 |, M9 w3 }: ~2 e解决:若是定义的变量确实没有用,删除掉;若是有用,则在程序中使用.
; m; j( V& \# v- U与该警告类似的还有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced$ C* V/ F3 j9 Y  z
8 `: J9 D  D/ h8 _2 U7 u4 R4 Q
6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"
# r, h+ m# O  H" A1 E3 K描述:返回非空的函数"DealwithInspect2"的最后缺少返回值声明.如:' `/ s7 W/ c4 E
int DealwithInspect2(uint32 test)
( |( N* {  @8 v7 L{* o" f+ g% E% s& {- j9 Q  d& R
...2 E4 C( g' Q0 F1 G
...
% ]; E0 }8 S$ r$ r. p8 g* k...
3 x% f0 k8 ~' E% f8 e: m/ w- X! Z6 q//此处应该是return x;返回一个int型数据,若是没有返回值,编译器产生警告9 i0 z  K" ]( S- p" m; c6 n
}
. W- D! c) `( l6 `6 D- h, H8 k! r$ j6 D  t9 \1 N, B( a
7.* {. t2 J6 W+ i( S
% q0 q" L) e3 _3 E% y
1. error: #65: expected a ";"
: s6 a2 A: }* t' N描述:缺少分号.大多是漏忘';'.
2 R1 R+ X4 }! l解决:双击错误行,在定位到错误点的附近找到没加';'号的语句,加上分号.并不一定在定位到的错误行才却分号,可能是这行的上一行,也可能是下一行.
4 f- w+ h% f) d/ R, l/ R) e; K
( h  L* p- r* k. L2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一块出现,而且后面的error: #20错误可能一大堆9 q+ H6 k2 N4 ^' M) d& K
描述:这个错误对于第一次遇上的人来说绝对是个噩梦,当错误出现,满怀希望的双击错误提示,来到错误行时却愕然发现,错误行绝对没有错,于是找找错误行的上一行,下一行,没有错误,再找上上行,下下行...让人无比郁闷的事情出现了:编译提示的所有错误行都不可能有错误出现.其实这最可能是你在.h文件声明外部变量或者函数时,没有在声明语句的最后加分号!如果你有很多模块,如main.c,lcd.c,key.c...有很多头文件,如lcd.h,key.h,若是在lcd.h文件声明函数时没有加分号,那么这种错误可能定为到main.c中,所以要检查所有头文件.
/ _4 p8 `4 h9 q8 c% S" ]8 D解决:仔细检查.h文件,将分号补上.
* @, }; b& f5 X7 D7 x7 d" {$ O2 D+ v
3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).
/ m. I. m( E8 u# O
5 P7 r3 G5 j0 Z; `1 i描述:变量(也是一种符号)flagu多处定义(在uart0.c中和main.c都定义了).通常错在全局变量定义重复.比如:在main.c中定义全局变量flagu:
: \/ U1 p4 ]) L8 Q! h% ^+ L( I  L1 J
uint8 flagu=0;
( B2 @: u: l+ e0 O) |8 Z" I6 |( F  i
在uart0.c中也用到该变量,于是声明此变量,我通常都是先复制定义的变量再在变量前面加关键字extern修饰:! F# q) k1 p7 K7 I% |
6 F+ ~- c) C8 P$ {; Y9 N
extern uint8 flagu=0;
! s6 ?5 U% k) \" y# H% P  |. O2 V
! y% _- E1 g  f0 x; B9 {. h然后编译,就会出现上面的连接错误,原因在于,我在uart0.c中是又定义了一个变量,而不是声明变量,因为我给变量赋了初值"flagu=0",这样就重复定义了变量flag.正确的声明方法是去掉赋值部分:
( s8 x- Q# E; e. {" T, x  k, x" e, I7 S' ?1 f
extern uint8 flagu;. u+ F3 ^0 ^7 \" e2 E

; P) F' o/ R( }3 o6 o. p0 G6 M5 M3 ?解决办法:找到重复定义的变量,看情况修改一处.
/ {6 A# e( u! Z+ P, X9 ]# x$ l2 K- A. v/ ~- D
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)
- ]  o7 Y( V# D5 @* x6 \4 x描述:在wr_lcd函数还没有声明之前就已经使用了.多出现在两种情况:第一种,wr_lcd函数体还没有写,就已经用到了它,这种情况多出现在写一个程序的大体结构中,只是简单写一下框架.第二种情况比较常见,函数a调用函数b,但函数b的函数体在函数a的下面:4 I6 D- k; y! ^( z/ ^
void a(void) //函数a的实体
& X! @/ `" s+ m; ]2 h2 Z4 y* n" k{6 \/ `% z& Q, `9 H2 I$ e
b(); //调用函数b3 G' F. q( s3 T+ i. q
}, ~$ g3 r0 C& n' d" f, @: i& Y

7 s2 [' k* C. z4 _4 ~) Ivoid b(void) //函数b的实体4 |6 Q. x; _# T" A" H  c) k! V
{
) a1 I: X# e+ @/ B+ g+ p1 p...
9 \  x$ M* ?) w$ d, j5 `}
# x, A0 S* n' r! z5 A0 M' [这样如果点编译,就会产生error: #159的错误,因为当函数a调用函数b时,发现在这之前都没有函数b的任何声明.
; i. v8 y+ M8 {1 `0 M: L& T解决方法:在函数a调用函数b之前,对函数b进行声明,如:
+ K7 l, w# [2 I( j6 j5 q4 e2 S; rvoid b(void); //对函数b进行声明
1 ?* c3 T; r" l8 A: ?1 t! [! A) P. \) i2 L2 [; q- t  b# |
void a(void) //函数a的实体
+ n' a7 b& g+ ^{
( j2 |: P9 |/ P+ S' w; X# d$ o7 yb(); //调用函数b
+ _7 ]6 ^- f( H- j  s9 J}5 c( K0 A# U+ E  ]
( A/ Z& P& K) U
void b(void) //函数b的实体" ]/ j- o8 G& b: k  p
{# r0 ~# q$ r2 u
.... s- B  A  z, A# ]! P% `1 m4 f
}
2 ]% b* e) C! D. C8 y: x

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-26 09:38 , Processed in 0.140625 second(s), 24 queries , Gzip On.

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

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

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