條件包含和條件函式簽名修改
為了有條件地包含一個程式碼塊,前處理器有幾個指令(例如 #if
,#ifdef
,#else
,#endif
等)。
/* Defines a conditional `printf` macro, which only prints if `DEBUG`
* has been defined
*/
#ifdef DEBUG
#define DLOG(x) (printf(x))
#else
#define DLOG(x)
#endif
普通 C 關係運算子可用於 #if
條件
#if __STDC_VERSION__ >= 201112L
/* Do stuff for C11 or higher */
#elif __STDC_VERSION__ >= 199901L
/* Do stuff for C99 */
#else
/* Do stuff for pre C99 */
#endif
#if
指令的行為類似於 C if
語句,它只包含整數常量表示式,並且不包含強制轉換。它支援一個額外的一元運算子 defined( identifier )
,如果定義了識別符號則返回 1
,否則返回 0
。
#if defined(DEBUG) && !defined(QUIET)
#define DLOG(x) (printf(x))
#else
#define DLOG(x)
#endif
條件函式簽名修改
在大多數情況下,應用程式的釋出版本應該具有儘可能少的開銷。但是,在測試臨時構建期間,其他日誌和有關問題的資訊可能會有所幫助。
例如,假設有一些函式 SHORT SerOpPluAllRead(PLUIF *pPif, USHORT usLockHnd)
,在進行測試構建時,需要生成關於其使用的日誌。但是,此功能在多個地方使用,並且希望在生成日誌時,部分資訊是知道呼叫函式的位置。
因此,使用條件編譯,你可以在包含檔案宣告函式中使用以下內容。這將使用函式的除錯版本替換函式的標準版本。前處理器用於替換函式 SerOpPluAllRead()
的呼叫,呼叫函式 SerOpPluAllRead_Debug()
,帶有兩個附加引數,檔名和函式使用位置的行號。
條件編譯用於選擇是否使用除錯版本覆蓋標準函式。
#if 0
// function declaration and prototype for our debug version of the function.
SHORT SerOpPluAllRead_Debug(PLUIF *pPif, USHORT usLockHnd, char *aszFilePath, int nLineNo);
// macro definition to replace function call using old name with debug function with additional arguments.
#define SerOpPluAllRead(pPif,usLock) SerOpPluAllRead_Debug(pPif,usLock,__FILE__,__LINE__)
#else
// standard function declaration that is normally used with builds.
SHORT SerOpPluAllRead(PLUIF *pPif, USHORT usLockHnd);
#endif
這允許你使用一個版本覆蓋函式 SerOpPluAllRead()
的標準版本,該版本將在呼叫函式的檔案中提供檔名和行號。
有一個重要的考慮因素: 使用此函式的任何檔案都必須包含使用此方法的標頭檔案,以便前處理器修改函式。否則,你將看到連結器錯誤。
函式的定義如下所示。此源的作用是請求前處理器將函式 SerOpPluAllRead()
重新命名為 SerOpPluAllRead_Debug()
並修改引數列表以包含兩個附加引數,指向呼叫函式的檔名稱的指標以及檔案中的行號使用該功能。
#if defined(SerOpPluAllRead)
// forward declare the replacement function which we will call once we create our log.
SHORT SerOpPluAllRead_Special(PLUIF *pPif, USHORT usLockHnd);
SHORT SerOpPluAllRead_Debug(PLUIF *pPif, USHORT usLockHnd, char *aszFilePath, int nLineNo)
{
int iLen = 0;
char xBuffer[256];
// only print the last 30 characters of the file name to shorten the logs.
iLen = strlen (aszFilePath);
if (iLen > 30) {
iLen = iLen - 30;
}
else {
iLen = 0;
}
sprintf (xBuffer, "SerOpPluAllRead_Debug(): husHandle = %d, File %s, lineno = %d", pPif->husHandle, aszFilePath + iLen, nLineNo);
IssueDebugLog(xBuffer);
// now that we have issued the log, continue with standard processing.
return SerOpPluAllRead_Special(pPif, usLockHnd);
}
// our special replacement function name for when we are generating logs.
SHORT SerOpPluAllRead_Special(PLUIF *pPif, USHORT usLockHnd)
#else
// standard, normal function name (signature) that is replaced with our debug version.
SHORT SerOpPluAllRead(PLUIF *pPif, USHORT usLockHnd)
#endif
{
if (STUB_SELF == SstReadAsMaster()) {
return OpPluAllRead(pPif, usLockHnd);
}
return OP_NOT_MASTER;
}