C 语言条件包含与条件函数签名修改
示例
有条件地包括一个代码块,则预处理器具有多个指令(例如#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
#if条件可以使用普通C关系运算符
#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
条件函数签名修改
在大多数情况下,应用程序的发布版本预计将具有尽可能少的开销。但是,在测试临时版本时,其他日志和有关发现的问题的信息可能会有所帮助。
例如,假设有一些功能SHORTSerOpPluAllRead(PLUIF*pPif,USHORTusLockHnd),当进行测试构建时,它会生成有关其使用的日志。但是,此函数在多个地方使用,并且希望在生成日志时,部分信息是要知道从哪里调用该函数。
因此,使用条件编译,您可以在包含文件中声明该功能的内容如下。这将功能的标准版本替换为功能的调试版本。预处理程序用于使用两个附加参数(文件名和使用函数的行号)替换对函数SerOpPluAllRead()的调用SerOpPluAllRead_Debug()。
条件编译用于选择是否用调试版本覆盖标准功能。
#if 0 //函数的调试版本的函数声明和原型。 SHORT SerOpPluAllRead_Debug(PLUIF *pPif, USHORT usLockHnd, char *aszFilePath, int nLineNo); //宏定义,以将旧名称替换为带有附加参数的debug函数的函数调用。 #define SerOpPluAllRead(pPif,usLock) SerOpPluAllRead_Debug(pPif,usLock,__FILE__,__LINE__) #else //通常与构建一起使用的标准函数声明。 SHORT SerOpPluAllRead(PLUIF *pPif, USHORT usLockHnd); #endif
这样,您就可以SerOpPluAllRead()使用将提供函数调用位置的文件名和行号的版本覆盖该函数的标准版本。
有一个重要的考虑因素:使用此功能的任何文件都必须包含使用此方法的头文件,以便预处理器修改该功能。否则,您将看到链接器错误。
该函数的定义如下所示。该消息源的作用是请求预处理器将函数重命名为该函数SerOpPluAllRead(),SerOpPluAllRead_Debug()并修改参数列表以包括两个附加参数,即指向调用该函数的文件名的指针以及该文件所在的行号。使用功能。
#if defined(SerOpPluAllRead) //转发声明替换函数,一旦我们创建日志,我们将调用它。 SHORT SerOpPluAllRead_Special(PLUIF *pPif, USHORT usLockHnd); SHORT SerOpPluAllRead_Debug(PLUIF *pPif, USHORT usLockHnd, char *aszFilePath, int nLineNo) { int iLen = 0; char xBuffer[256]; //仅打印文件名的后30个字符以缩短日志。 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); //现在我们已经发布了日志,继续进行标准处理。 return SerOpPluAllRead_Special(pPif, usLockHnd); } //我们在生成日志时的特殊替换功能名称。 SHORT SerOpPluAllRead_Special(PLUIF *pPif, USHORT usLockHnd) #else //标准的,正常的功能名称(签名),已由我们的调试版本取代。 SHORT SerOpPluAllRead(PLUIF *pPif, USHORT usLockHnd) #endif { if (STUB_SELF == SstReadAsMaster()) { return OpPluAllRead(pPif, usLockHnd); } return OP_NOT_MASTER; }