2011-10-10 86 views
3

在因特網上搜索一個解決方案後,我決定詢問我的解決方案是否正常。使用MACROS禁用功能

我正在嘗試編寫一個簡單的模塊化C日誌庫,旨在簡化禁用並特別幫助博士生和研究人員調試算法,儘可能減少日誌記錄系統的影響。

我的問題是,我想爲圖書館的用戶禁止在編譯時記錄系統生成可執行其中記錄器的成本是0

C代碼是這樣做可能:

... 
logger_t * logger; 

result = logger_init(logger); 
if(result == -1) {...} 
... 

這將簡單地初始化記錄器。尋找一個示例代碼我已經檢查過assert.h頭文件,但是在我的情況下,結果會產生警告列表。事實上,如果使用宏將logger_init()替換爲0,這將導致變量記錄器從不使用。

出於這個原因,我決定用這個辦法:

int logger_init(logger_t *logger); 

#ifndef NLOG /* NLOG not defined -> enable logging */ 
int logger_init(logger_t *logger) { 
... 
} 
#else /* NLOG defined --> the logging system must be disabled */ 
#define logger_init(logger)  (int)((logger = NULL) == NULL) 
#endif /* NLOG */ 

這不會導致警告,我也避免調用函數的開銷。實際上我的第一次嘗試是這樣做的:

即使我不需要它也會繼續調用該函數。

您認爲我的解決方案可以被認爲是一個很好的解決方案嗎?有更好的解決方案嗎?

非常感謝,夥計們! 乾杯, 阿曼多

+2

空函數完成這項工作,編譯器將它們內聯,然後將它們移除 – paulm

回答

7

標準成語,至少在90年代,是:

#ifndef NLOG 
void logger_init(logger_t *logger); 
void logger_log(logger_t *logger, ...); 
#else 
#define logger_init (void)sizeof 
#define logger_log (void)sizeof 
#endif 

記住的sizeof操作數沒有評估,雖然他們是語法檢查。 這招作品也有可變參數的功能,因爲sizeof操作符會看到爲一個函數與幾個逗號運營商:

logger_log(log, 1, 2, 3); 

轉換爲:

(void)sizeof(log, 1, 2, 3); 

那些逗號不分離參數(sizeof不是功能但運營商),但他們是逗號運營商

請注意,我將返回值從int更改爲void。沒有真正的需要,但sizeof回報將是無意義的。

+0

絕對清楚。我會堅持這個解決方案!感謝很多 – Armando

+0

現在嘗試解決方案,結果產生這樣的警告:「警告:由於傳遞給操作符sizeof的參數列表,逗號表達式的左側操作數沒有任何影響[-Wunused-value]」。什麼可能是一個工作周圍? – Armando

+0

編寫一個什麼也不做的代碼是很困難的,並且同時避免所有關於代碼無關的編譯器警告。即使你使用智能技巧,每當你升級你的編譯器時,你都會再次得到警告。所以我的建議是在編譯器命令中加上-Wno-unused-value。其他選項是'#define logger_init(x)(void)0',但如果你有可變參數函數,你也需要可變參數宏。您可能會因爲其他原因獲得未使用的警告...... – rodrigo

0

無法將禁用的版本僅僅是一個常數:

#ifndef NLOG /* NLOG not defined -> enable logging */ 
int logger_init(logger_t *logger) { 
... 
} 
#else /* NLOG defined --> the logging system must be disabled */ 
#define logger_init(logger)  0 
#endif /* NLOG */ 

這樣一來,你就必須(在預編譯):result = 0;不應產生任何警告。

+0

正如我寫的,這樣做的問題是變量記錄器不再需要,編譯器會因此而引發警告。 – Armando

+0

對不起,誤讀了那一點......會再想一想! – asc99c