printf 巨集 除錯技巧

2021-08-28 21:20:03 字數 2870 閱讀 4596

printf除錯是嵌入式除錯的基本手段,而且是非常重要的手段,我認為相比單步除錯更加有用有效,特別是微控制器之後跑系統,單步除錯效率更加低下了,我們在工作遇到bug的時候,我們第一時間就想知道那些該死的日誌有沒有儲存下來,這樣好讓我們程式設計師裝逼一波把問題解決。

printf巨集定義除錯非常重要,有些日誌在開發的時候才需要開啟,發布的時候需要關閉,但是在**上又需要保留下次除錯,所以我們在除錯的時候才開啟除錯巨集定義,而且printf會占用空間,很多晶元的空間非常有限,更應該關閉除錯巨集。

下面就直接進入正題,說一下除錯的技巧

先介紹幾個編譯器內建的巨集定義,這些巨集定義不僅可以幫助我們完成跨平台的原始碼編寫,靈活使用也可以巧妙地幫我們輸出非常有用的除錯資訊。

ansi c標準中有幾個標準預定義巨集(也是常用的):

__line__:在源**中插入當前源**行號;

__file__:在原始檔中插入當前源檔名;

__date__:在原始檔中插入當前的編譯日期

__time__:在原始檔中插入當前編譯時間;

__stdc__:當要求程式嚴格遵循ansi c標準時該標識被賦值為1;

__cplusplus:當編寫c++程式時該識別符號被定義。

編譯器在進行原始碼編譯的時候,會自動將這些巨集替換為相應內容。

開啟巨集的時候輸出

關閉巨集的時候輸出

#include #define __debug__

#ifdef __debug__

#define debug(format,...) printf("date: "__date__",file: "__file__", line: %05d: "format"\n", __line__, ##__va_args__)

#else

#define debug(format,...)

#endif

int main(int argc, char **argv)

輸出如下

date: oct  5 2018,file: /code/main.c, line: 00013: hello world

sandbox> exited with status 0

在gnu c中,巨集可以接受可變數目的引數,就象函式一樣

例如:

#define pr_debug(fmt,arg...) \ 

printk(kern_debug fmt, ##arg)

用可變引數巨集(variadic macros)傳遞可變參數列 

你可能很熟悉在函式中使用可變參數列,如:

void printf(const char* format, ...);
直到最近,可變參數列還是只能應用在真正的函式中,不能使用在巨集中。

c99編譯器標準允許你可以定義可變引數巨集(variadic macros),這樣你就可以使用擁有可以變化的參數列的巨集。可變引數巨集就像下面這個樣子:

#define debug(...) printf(__va_args__)
預設號代表乙個可以變化的參數列。使用保留名 __va_args__ 把引數傳遞給巨集。當巨集的呼叫展開時,實際的引數就傳遞給 printf()了

例如:

debug("y = %d\n", y);
而處理器會把巨集的呼叫替換成: 

printf("y = %d\n", y);
因為debug()是乙個可變引數巨集,你能在每一次呼叫中傳遞不同數目的引數: 

debug("test");// 乙個引數
用gcc和c99的可變引數巨集, 更方便地列印除錯資訊

可變引數巨集不被ansi/iso c++ 所正式支援。因此,你應當檢查你的編譯器,看它是否支援這項技術。 

可變引數的巨集裡的'##'操作說明帶有可變引數的巨集(macros with a variable number of arguments)

更詳細請檢視如下鏈結

下面是android touchscreen驅動的除錯巨集用法,看這樣的寫法就是乙個大神了,給大家借鑑。

// log define

#define gtp_error(fmt,arg...)          printk("<<-gtp-error->> "fmt"\n",##arg)

#if debug_switch

#define gtp_info(fmt,arg...)           printk("<<-gtp-info->> "fmt"\n",##arg)

#define gtp_debug(fmt,arg...)          dowhile(0)

#define gtp_debug_array(array, num)    do\

}\printk("\n");\

}\}while(0)

#define gtp_debug_func()               dowhile(0)

#else

#define gtp_info(fmt,arg...)

#define gtp_debug(fmt,arg...)

#define gtp_debug_array(array, num)

#define gtp_debug_func()

#endif

除錯技巧 巨集定義開關和printf

printf 的巨集定義版本 前言 我們在寫程式的時候,總是或多或少會加入一些printf之類的語句用於輸出除錯資訊,但是printf語句有個很不方便的地方就是當我們需要發布程式的時候要一條一條的把這些語句刪除,而一旦需要再次除錯的時候,這些語句又不得不一條條的加上,這給我們帶來了很大的不便,浪費了...

C語言 設計printf除錯巨集

借除錯巨集的設計,梳理下c語言巨集的用法 嵌入式裝置基本會配置rs232串列埠作為除錯io介面,假設底層串列埠單位元組輸出函式為serial putchar 利用fputc 和fputs 重定向printf函式 void fputc int byte,file stream void fputs c...

Linux printf 巨集 除錯技巧

printf除錯是嵌入式除錯的基本手段,而且是非常重要的手段,我認為相比單步除錯更加有用有效,特別是微控制器之後跑系統,單步除錯效率更加低下了,我們在工作遇到bug的時候,我們第一時間就想知道那些該死的日誌有沒有儲存下來,這樣好讓我們程式設計師裝逼一波把問題解決。printf巨集定義除錯非常重要,有...