__VA_ARGS__的使用
Reference:
1. http://blog.linux.org.tw/~jserv/
2. http://www.jeffhung.net/blog/articles/jeffhung/1013/
3. http://www.cash.idv.tw/wordpress/?p=1531
4. http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
__VA_ARGS__是一個可變的marco(Variadic Macros)。為什麼要使用這個功能呢?在code中避免用到太多的#ifndef/#endif,當你的code充滿#ifndef/#endif會讓你的code變得很難閱讀跟理解,所以可以利用__VA_ARGS__跟marco來取代#ifndef/#endif。
當寫程式的過程通常會需要輸出一些訊息,來方便我們Debug。程式會分測試版跟釋出版,所以常常用大量使用#ifndef/#endif,當然使用#ifndef/#endif這種方式也不是不可以,但是就跟剛剛講得code會變得很難閱讀,所以可以多多利用__VA_ARGS__。
首先來瞭解__VA_ARGS__能做什麼。直接看以下的範例,當我定義一個marco叫做DBG(...),括號中的... 。就是說你可以輸入任何的參數,然後就可以用__VA_ARGS__來代表...所傳入的參數。
以下的範例很簡單,當我DEBUG的Flag設定為1,這個時候printf("Hello World\n");才會出現在編譯完的檔案,但這種寫法不是很好,所以只是參考用以方便瞭解__VA_ARGS__。
要注意由於__VA_ARGS__是C99新增的功能,所以要確定compiler是否有無支援,需要使用到__STDC_VERSION__ 這個 predefined macro name。接下來範例將會說明:
在編譯的指令需要注意如果使用gcc必須加上-std=c99時,編譯才會過還有我也去判斷有沒有NDBUG這個marco有沒有存在,來決定我在編譯的時候是不是要列印出我要的訊息。
gcc -DNDEBUG -std=c99 -o main main.c
gcc -D的定義:
-D name
Predefine name as a macro, with definition 1
1. http://blog.linux.org.tw/~jserv/
2. http://www.jeffhung.net/blog/articles/jeffhung/1013/
3. http://www.cash.idv.tw/wordpress/?p=1531
4. http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
__VA_ARGS__是一個可變的marco(Variadic Macros)。為什麼要使用這個功能呢?在code中避免用到太多的#ifndef/#endif,當你的code充滿#ifndef/#endif會讓你的code變得很難閱讀跟理解,所以可以利用__VA_ARGS__跟marco來取代#ifndef/#endif。
當寫程式的過程通常會需要輸出一些訊息,來方便我們Debug。程式會分測試版跟釋出版,所以常常用大量使用#ifndef/#endif,當然使用#ifndef/#endif這種方式也不是不可以,但是就跟剛剛講得code會變得很難閱讀,所以可以多多利用__VA_ARGS__。
首先來瞭解__VA_ARGS__能做什麼。直接看以下的範例,當我定義一個marco叫做DBG(...),括號中的... 。就是說你可以輸入任何的參數,然後就可以用__VA_ARGS__來代表...所傳入的參數。
以下的範例很簡單,當我DEBUG的Flag設定為1,這個時候printf("Hello World\n");才會出現在編譯完的檔案,但這種寫法不是很好,所以只是參考用以方便瞭解__VA_ARGS__。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h> |
#Output
|
要注意由於__VA_ARGS__是C99新增的功能,所以要確定compiler是否有無支援,需要使用到__STDC_VERSION__ 這個 predefined macro name。接下來範例將會說明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdio.h> |
在編譯的指令需要注意如果使用gcc必須加上-std=c99時,編譯才會過還有我也去判斷有沒有NDBUG這個marco有沒有存在,來決定我在編譯的時候是不是要列印出我要的訊息。
gcc -DNDEBUG -std=c99 -o main main.c
gcc -D的定義:
-D name
Predefine name as a macro, with definition 1
#Output
|
但是這種寫法在switch-case會出現有趣的現象,可以參考Reference 1的範例。
因為我也是最近才看到這種用法所以也沒辦法寫的更多,之後有更多的心得再來分享。
以下的範例是從Reference 2來的,我覺得這是一個Debug不錯用的code,如果要更加清楚內容請到原作者的網站看,他說得很清楚,我這邊只是備份以方便我自己以後要用 :p
因為我也是最近才看到這種用法所以也沒辦法寫的更多,之後有更多的心得再來分享。
以下的範例是從Reference 2來的,我覺得這是一個Debug不錯用的code,如果要更加清楚內容請到原作者的網站看,他說得很清楚,我這邊只是備份以方便我自己以後要用 :p
#include <stdio.h>#include <stdarg.h> void dprintf_impl(const char* file, size_t line, int enable, const char* fmt, ...) { va_list ap; if (enable) { fprintf(stderr, "%s (%d): ", file, line); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); fflush(stderr); } } #ifndef NDEBUG # if (__STDC_VERSION__ < 199901L) # error "Please use a newer compiler that support __VA_ARGS__." # else # define DPRINTF(enable, ...) \ dprintf_impl(__FILE__, __LINE__, enable, __VA_ARGS__) # endif #else # define DPRINTF(enable, ...) // define to nothing in release mode #endif int main() { int enable = 1; int i = 3; DPRINTF(enable, "i == %d", i); return 0; }
留言