程式除錯時常需要加些 log 印出變數內容, 通常會希望附帶印出所在的函式。每次要自己重打一次函式名稱太麻煩了, 可以利用 C 的 macro 避免重覆的動作。
先來看個範例程式:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#ifdef DEBUG_PRINT | |
#define DebugPrintf(format, args...) fprintf(stderr, "%s this=%p " format, __PRETTY_FUNCTION__, this, ##args) | |
#else | |
#define DebugPrintf(format, args...) | |
#endif | |
class Calculator | |
{ | |
public: | |
int add(int a, int b) | |
{ | |
DebugPrintf("a = %d, b = %d\n", a, b); | |
return a + b; | |
} | |
}; | |
int main(void) | |
{ | |
Calculator c; | |
printf("result: %d\n", c.add(2, 1)); | |
return 0; | |
} |
以及輸出結果:
$ g++ a.cpp -o a; ./a result: 3 $ g++ -DDEBUG_PRINT a.cpp -o a; ./a int Calculator::add(int, int) this=0x7ffff03c1d7f a = 2, b = 1 result: 3
有 #define DEBUG_PRINT 的才會真的執行 DebugPrintf, 除了兼顧原本 printf 有的變動式參數外, 順便自動補上函式名稱和目前物件的指標; 反之則完全不會執行到, 不會增加額外負擔。
有需要的話, 可以稍微修改 DebugPrintf, 如同 《trace C/C++ function call 的方法》 記錄檔名和行數。
關於巨集這行:
#define DebugPrintf(format, args...) fprintf(stderr, "%s this=%p " format, __PRETTY_FUNCTION__, this, ##args)
用到的語法包含:
- C 的 "abc" "def" 會組成 "abcdef"
- args... 比 __VA_ARGS__ 易於閱讀
- 只有一個參數的時候, __VA_ARGS__ 會自動移掉前一個 ","
可以參照 Variadic Macros - The C Preprocessor 了解細節。
沒有留言:
張貼留言