2012-10-23 88 views
0

C89 GCC 4.7.4格式化與可變參數變量

你好,

我只是用宏這樣的實驗:

#define LOG_INFO_1(fmt, ...) printf(fmt, __VA_ARGS__) 
#define LOG_INFO_2(...) printf(__VA_ARGS__) 

而且使用這樣的:

LOG_INFO_1("%s:%d", __func__, __LINE__); 
LOG_INFO_2("%s:%d", __func__, __LINE__); 

輸出提供完全相同的格式。我只是想知道在我的第一個宏中使用fmt參數有什麼好處?它似乎並不是真的需要。我怎麼能利用它?

非常感謝您的任何建議,

+2

如果您只想傳遞格式字符串,例如, 'LOG_INFO_1(「只是一個簡單的字符串」)'。當你這樣做時,'LOG_INFO_1'會導致編譯器錯誤,因爲調用'printf'後面的逗號(因爲'__VA_ARGS__'在這種情況下擴展爲空字符串),而'LOG_INFO_2'將正確擴展。 –

回答

5

指定第一個參數是fmt對編譯器/計算機沒有任何影響。

但是,我認爲這對其他可能會使用您的代碼的程序員有很大的影響。

看着LOG_INFO_1(fmt, ...),我看到一個強烈的提示,這個宏在後面接受一個帶有附加參數的printf樣式格式字符串。

看着LOG_INFO_2(...),我不知道應該傳遞什麼參數,或者以什麼順序。也許第一個參數應該是RFC 5424嚴重性代碼?也許它應該是一個輸出流寫入?宏中沒有提示答案。

我認爲您應該儘可能地指定後面的程序員,讓工作更輕鬆,並且僅在絕對必要時留下含糊之處,如...

2

對於宏而言,使用哪種變體並不重要。預處理器將從這兩個宏中生成相同的C代碼。


對於可變參數函數,至少需要定義一個參數。

所以

void foo(const char * fmt, ...); 

將編譯,而

void bar(...); 

不會。

1

看看ACE_DEBUG/Log_Msg。 ACE(自適應通信環境)是一種建立的用於網絡的C++框架。他們以類似的方式實現了一個使用宏和變量變量的線程安全日誌架構。