工作後從單片機轉成ARM,剛開始用ADS1.2編譯器,用了一段時間,因為我接手的項目的老程式正是用ADS編譯的,部門也大都在用.在學單片機的時候用的是keil c51編譯器,ads和這個編譯器在易用性上真是無法比較.後來漸漸知道keil已經被arm公司收購,現在keil MDK成為了arm官方編譯器,是以決定重新投奔keil,利用平時的時間,将原程式重新用mdk編譯.mdk的優點就沒必要說了,在這裡把平時遇到的編譯器給出的警告和錯誤資訊給出詳解,希望給初學者一點幫助,發現錯誤,需要補充的歡迎留言.
1.warning: #550-D: variable "d" was set but never used
描述:變量'd'定義但從未使用,或者是,雖然這個變量你使用了,但編譯器認為變量d所在的語句沒有意義,編譯器把它優化了.
解決:仔細衡量所定義的變量d是否有用,若是認定變量d所在語句有意義,那麼嘗試用volatile關鍵字修飾變量d,若是真的沒有用,那麼删除掉以釋放可能的記憶體.
2.warning: #1-D: last line of file ends without a newline
描述:檔案最後一行不是新的一行.編譯器要求程式檔案的最後一行必須是空行,想了半天沒想通為什麼要這樣.
解決:可以不理會.若是覺得出現警告不爽,那麼在出現警告的檔案的最後一行敲個回車,空出一行.
3. warning: #111-D: statement is unreachable
描述:聲明不可能到達.多出現在這種場合:
int main(void)
{
...
while(1) //無限循環,這在不使用作業系統的程式中最常見
{
...
}
return 0; //這句聲明在正常情況下不可能執行到,編譯器發出警告
}
解決:不理會.
4. warning: C3017W: data may be used before being set
描述:變量'data'在使用前沒有明确的指派.如:
uint8 i,data; //定義變量i和data,二者都沒有明确指派
for ( i = 0; i < 8; i++) //變量'i'在語句中被指派0
{
if ( IO1PIN & SO_CC2420 )
data |= 0x01; //變量'data'在使用前沒有明确指派,編譯器發出警告
else
data &= ~0x01;
}
解決:應仔細衡量該變量的初始值是否為0,若是,可以不理會這個警告,因為MDK編譯器在程式執行前,會将使用到的資料區初始化為0,但若是該變量的初始值不應該是0,忽略這個警告可能會引起緻命錯誤.這個警告應引起足夠重視.應養成變量賦初值的習慣,好在有編譯器給把關.
5. warning: #177-D: variable "temp" was declared but never referenced
描述:變量'temp'進行了聲明但沒有引用.多出現在聲明了一個變量,但卻沒有使用它,它和warning: #550-D: variable "temp" was set but never used不同之處在于temp從沒有使用過.
解決:若是定義的變量确實沒有用,删除掉;若是有用,則在程式中使用.
與該警告類似的還有 warning: #177-D: function "MACProcessBeacon" was declared but never referenced
6. warning: #940-D: missing return statement at end of non-void function "DealwithInspect2"
描述:傳回非空的函數"DealwithInspect2"的最後缺少傳回值聲明.如:
int DealwithInspect2(uint32 test)
{
...
...
...
//此處應該是return x;傳回一個int型資料,若是沒有傳回值,編譯器産生警告
}
7..warning: #1295-D: Deprecated declaration lcd_init - give arg types
描述:在定義函數的時候,如果你寫上函數參數,就會有這個警告,比如void timer_init(); 這裡就沒有形參,如果這樣的話,編譯器會給出警告.
1. error: #65: expected a ";"
描述:缺少分号.大多是漏忘';'.
解決:輕按兩下錯誤行,在定位到錯誤點的附近找到沒加';'号的語句,加上分号.并不一定在定位到的錯誤行才卻分号,可能是這行的上一行,也可能是下一行.
2. error: #65: expected a ";"和 error: #20: identifier "xxxx" is undefined一塊出現,而且後面的error: #20錯誤可能一大堆
描述:這個錯誤對于第一次遇上的人來說絕對是個噩夢,當錯誤出現,滿懷希望的輕按兩下錯誤提示,來到錯誤行時卻愕然發現,錯誤行絕對沒有錯,于是找找錯誤行的上一行,下一行,沒有錯誤,再找上上行,下下行...讓人無比郁悶的事情出現了:編譯提示的所有錯誤行都不可能有錯誤出現.其實這最可能是你在.h檔案聲明外部變量或者函數時,沒有在聲明語句的最後加分号!如果你有很多子產品,如main.c,lcd.c,key.c...有很多頭檔案,如lcd.h,key.h,若是在lcd.h檔案聲明函數時沒有加分号,那麼這種錯誤可能定為到main.c中,是以要檢查所有頭檔案.
解決:仔細檢查.h檔案,将分号補上.
3. Error: L6200E: Symbol flagu multiply defined (by uart0.o and main.o).
描述:變量(也是一種符号)flagu多處定義(在uart0.c中和main.c都定義了).通常錯在全局變量定義重複.比如:在main.c中定義全局變量flagu:
uint8 flagu=0;
在uart0.c中也用到該變量,于是聲明此變量,我通常都是先複制定義的變量再在變量前面加關鍵字extern修飾:
extern uint8 flagu=0;
然後編譯,就會出現上面的連接配接錯誤,原因在于,我在uart0.c中是又定義了一個變量,而不是聲明變量,因為我給變量賦了初值"flagu=0",這樣就重複定義了變量flag.正确的聲明方法是去掉指派部分:
extern uint8 flagu;
解決辦法:找到重複定義的變量,看情況修改一處.
4.error: #159: declaration is incompatible with previous "wr_lcd" (declared at line 40)
描述:在wr_lcd函數還沒有聲明之前就已經使用了.多出現在兩種情況:第一種,wr_lcd函數體還沒有寫,就已經用到了它,這種情況多出現在寫一個程式的大體結構中,隻是簡單寫一下架構.第二種情況比較常見,函數a調用函數b,但函數b的函數體在函數a的下面:
void a(void) //函數a的實體
{
b(); //調用函數b
}
void b(void) //函數b的實體
{
...
}
這樣如果點編譯,就會産生error: #159的錯誤,因為當函數a調用函數b時,發現在這之前都沒有函數b的任何聲明.
解決方法:在函數a調用函數b之前,對函數b進行聲明,如:
void b(void); //對函數b進行聲明
void a(void) //函數a的實體
{
b(); //調用函數b
}
void b(void) //函數b的實體
{
...
}
5. error: #137: expression must be a modifiable lvalue
描述:表達式必須是一個可以修改的左值.主要出現在這種現象:
a=NUM;
NUM是一個數值或表達式,a為一個變量,但a被定義為像const這種不可更改的類型,導緻NUM不能指派給變量a.
解決方法:要麼放棄指派,要麼修改變量屬性.
6.error: #18: expected a ")"
如果是出現在c檔案中, 多半是因為少了一個")",或者錯誤行有編譯器不識别的字元
如果出現在頭檔案中,錯誤行又是一個函數聲明,多半是因為在函數聲明中有編譯器不認識的字元.
7.error: #7: unrecognized token
未識别的标記,多半是切換成了中文标點。
http://blog.csdn.net/zhzht19861011/article/details/5823537來自《
還不懂同學的專欄
》