DSP編程技巧之7---揭開編譯器神秘面紗之預(yù)處理與診斷
在編程軟件例如CCS中編程時,代碼分析工具可以方便我們對代碼進(jìn)行分析,例如我們把鼠標(biāo)指向一個函數(shù)名的時候,所指的地方就能出來一個實(shí)時菜單,使得我們可以直接定位到函數(shù)的聲明、被調(diào)用的位置或者某個宏定義等等,非常方便。這種功能是如何實(shí)現(xiàn)的呢?在編譯器的前端是一個語義解析器,它負(fù)責(zé)把源程序中的token找出來,然后解析器parser(也有的地方叫分析器)就可以解析這些token,并產(chǎn)生樹狀表,供編程環(huán)境使用;此外解析器還可以完成一部分的語法錯誤檢查功能。如果希望了解關(guān)于解析器的更詳細(xì)的信息,可以參考編譯原理方面最著名的“龍書”,即《Compliers: Principles, Techniques, &Tools》;在K&RC語言文檔的A12這一節(jié)中也對解析器的預(yù)處理功能進(jìn)行了詳細(xì)的敘述,它預(yù)處理的信息主要包括:
本文引用地址:http://m.butianyuan.cn/article/234414.htm1. 宏定義和擴(kuò)展,例如_INLINE;
2. #include引用的文件,包括<>和“”兩種方法引用的頭文件;
3. 條件編譯指令,例如#if,#endif等等;
4. 其它的多種預(yù)處理指令,主要是#開頭的一些指令,例如#error。
我們可以控制編譯器的預(yù)處理選項(xiàng),使得解析器根據(jù)我們的需求產(chǎn)生需要的預(yù)處理結(jié)果,方便我們對程序的開發(fā)調(diào)試;這些選項(xiàng)如表1所示。
表1 編譯器中解析器的預(yù)處理選項(xiàng)
預(yù)處理選項(xiàng) |
別名 |
控制效果 |
--preproc_dependency[=filename |
-ppd |
只執(zhí)行預(yù)處理操作,并不輸出預(yù)處理的解析結(jié)果,但是會并產(chǎn)生供make程序使用的列表文件,其中包含了被預(yù)處理的程序中存在的與頭文件中的定義關(guān)聯(lián)的行信息。 make程序是編譯器在編譯時調(diào)用的編譯程序。如果使用命令行的方法,可以不使用CCS而直接調(diào)用make程序進(jìn)行編譯。 |
--preproc_includes[=filename] |
-ppi |
只執(zhí)行預(yù)處理操作,但是會把包含#include指令的文件列表寫入列表文件。 |
--preproc_macros[=filename] |
-ppm |
只執(zhí)行預(yù)處理操作,會生成其中包含了預(yù)定義的和用戶自定義的宏的多個文件,這些文件和被預(yù)處理的文件的名字一樣,只是其擴(kuò)展名為.pp。 預(yù)定義的宏是TI預(yù)定義的,它在預(yù)處理結(jié)果中被用/* Predefined */標(biāo)注出。 |
--preproc_only |
-ppo |
只執(zhí)行預(yù)處理操作,并把解析的結(jié)果輸出為名字與輸入文件名一致、擴(kuò)展名為.pp的文件。 在這種模式下,#include文件中的信息會被復(fù)制到.pp文件中,宏定義和其它的一些預(yù)處理指令信息都會被完全展開。 |
--preproc_with_comment |
-ppc |
只執(zhí)行預(yù)處理操作,并把解析的結(jié)果輸出為名字與輸入文件名一致、擴(kuò)展名為.pp的文件;與-ppo相比,輸出的文件中保留了輸入程序中的注釋信息。 |
--preproc_with_compile |
-ppa |
在執(zhí)行預(yù)處理之后,繼續(xù)編譯工作。對比可以看出,在預(yù)處理選項(xiàng)中,除了-ppa之外,其余的幾個選項(xiàng)只完成預(yù)處理功能,并不進(jìn)行接下來的編譯工作。-ppa選項(xiàng)可以和其它的預(yù)處理選項(xiàng)一起使用,這樣既可以輸出預(yù)處理結(jié)果,又可以在預(yù)處理完成之后繼續(xù)編譯工作。 |
--preproc_with_line |
-ppl |
只執(zhí)行預(yù)處理操作,并把包含行控制信息(#line指令)的解析結(jié)果輸出為名字與輸入文件名一致、擴(kuò)展名為.pp的文件。 |
因?yàn)轭A(yù)處理器要使用到文件中的符號信息,所以相關(guān)的預(yù)定義信息一定要提供給預(yù)處理器,否則找不到符號信息就要報(bào)錯了。符號選項(xiàng)比較簡單,就是預(yù)定義與解除定義,如表2所示。
表2 預(yù)定義的符號選項(xiàng)
語言選項(xiàng) |
別名 |
控制效果 |
--define=name[=def] |
-D |
預(yù)定義符號,使用方法是--define=name=""string def""。在編譯器選項(xiàng)里使用-D,與在C程序里使用#define的效果是一樣的。 |
--undefine=name |
-U |
解除對某個符號的定義,它會覆蓋-D選項(xiàng)的效果。 |
在程序的處理過程中,我們可以控制編譯器輸出診斷信息選項(xiàng),使得它輸出我們期望的詳細(xì)信息,更加容易定位和解決一些看起來難以捉摸的問題;這些選項(xiàng)如表3所示。需要注意的是,診斷信息相關(guān)的選項(xiàng)必須放在鏈接器選項(xiàng)--run_linker之前。
表3編譯器的診斷信息選項(xiàng)
語言選項(xiàng) |
別名 |
控制效果 |
--compiler_revision |
|
在信息窗口中打印出編譯器的版本號。這個用處不太大,因?yàn)閺?/span>CCS的help的“關(guān)于”里面很容易看到。 |
--diag_error=num |
-pdse |
這里的num是診斷信息的標(biāo)識符。不顯示標(biāo)識符的話,在編譯出現(xiàn)錯誤時,會提示: error: a break statement may only be used within a loop or switch 啟用的話,在有錯誤的時候,會提示: error #77: this declaration has no storage class or type specifier xxxxx; -pdse是把標(biāo)識符num對應(yīng)的語句標(biāo)記為錯誤。 |
--diag_remark=num |
-pdsr |
把標(biāo)識符num對應(yīng)的語句標(biāo)記為提示。 |
--diag_suppress=num |
-pds |
把標(biāo)識符num對應(yīng)的語句標(biāo)記為不提示。 |
--diag_warning=num |
-pdsw |
把標(biāo)識符num對應(yīng)的語句標(biāo)記為警告。 |
--diag_wrap={on|off} |
|
默認(rèn)為on,打包診斷信息。 |
--display_error_number |
-pden |
把診斷信息標(biāo)識符和它對應(yīng)的文本說明一起顯示出來。 |
--emit_warnings_as_errors |
-pdew |
把警告信息作為錯誤處理。在這樣的嚴(yán)格的模式下,必須消除所有的警告和錯誤,編譯才能繼續(xù)。 |
--issue_remarks |
-pdr |
提示所有的提醒信息(即非嚴(yán)重的警告信息)。 |
--no_warnings |
-pdw |
不顯示警告信息,但是錯誤信息還是會提示的:畢竟有錯誤在的話編譯無法完成。 |
--quiet |
-q |
安靜模式,不顯示編譯過程中的診斷信息。 |
--set_error_limit=num |
-pdel |
這個選項(xiàng)設(shè)置編譯過程中錯誤的上限,比如有10個源程序,設(shè)定錯誤上限為5,假如第3個文件時就已經(jīng)有5個錯誤了,那么編譯器就停止了編譯,不再繼續(xù)編譯剩下的文件了。 |
--super_quiet |
-qq |
“超級安靜”模式。與-q相比,多了個q,足以看出它的級別。顯然它的處理速度最快,但是給出的診斷信息那是一個也沒有:最多告訴你程序有x個錯誤。如果確信程序完全無誤,用這個選項(xiàng)編譯倒是要快了不少。 |
--tool_version |
-version |
顯示編譯過程中調(diào)用的各個工具的版本信息。 |
--verbose |
|
啰嗦模式:顯示函數(shù)編譯過程中的處理信息。 |
--verbose_diagnostics |
-pdv |
在啰嗦模式的基礎(chǔ)上,把源程序中的對應(yīng)部分也顯示出來。 |
--write_diagnostics_file |
-pdf |
產(chǎn)生診斷信息文件。 |
c語言相關(guān)文章:c語言教程
評論