现在的位置: 首页 > 综合 > 正文

VC 宏与预处理使用方法总结

2013年12月08日 ⁄ 综合 ⁄ 共 5711字 ⁄ 字号 评论关闭

原文地址::http://blog.csdn.net/breakerzy/article/details/6908820

相关网帖

1.VC预处理指令与宏定义的妙用----http://blog.csdn.net/ningyaliuhebei/article/details/7545403

作者:Breaker Zhao
转载请注明作者和原文链接

VC 2005 中的宏 (#define) 与预处理 (#if/#ifdef/#pragma) 的使用方法总结。

关键字:宏, 预定义宏, 预处理, 预编译头, VC, #pragma, 编译选项, 程序区段

目录


VC 中的宏使用方法参考 MSDN: Macros (C/C++)

C/C++ 预定义宏^

__LINE__: 当前源文件的行号,整数
__FILE__: 当前源文件名,char 字符串,使用 /FC 选项产生全路径
__DATE__: 当前编译日期,char 字符串,格式 Aug 28 2011
__TIME__: 当前编译时间,char 字符串,格式 06:43:59
__STDC__: 整数 1,表示兼容 ANSI/ISO C 标准,配合 #if 使用
__TIMESTAMP__: 最后一次修改当前文件的时间戳,char 字符串,格式 Sun Aug 28 06:43:57 2011
__cplusplus: 以 C++ 方式而非 C 语言方式编译时定义,VC 2005 中定义为 199711L,配合 #ifdef 使用

例子:C/C++ 预定义宏的取值^

  1. // MacroTest.h  
  2. void PrintSourceInfo()  
  3. {  
  4.     const _TCHAR* pszstdc;  
  5.     const _TCHAR* pszcpp;  
  6.   
  7. #if __STDC__  
  8.     pszstdc = _T("YES");  
  9. #else  
  10.     pszstdc = _T("NO");  
  11. #endif  
  12.   
  13. #ifdef __cplusplus  
  14.     pszcpp = _T("YES");  
  15. #else  
  16.     pszcpp = _T("NO");  
  17. #endif  
  18.   
  19.     _tprintf(_T("File: %s, Line: %d, Date: %s, Time: %s, Timestamp: %s, ANSI/ISO C: %s, C++: %s\n"),  
  20.              _T(__FILE__), __LINE__, _T(__DATE__), _T(__TIME__), _T(__TIMESTAMP__), pszstdc, pszcpp);  
  21. }  
  22.   
  23. // 宏化的 PrintSourceInfo()  
  24. #define PRINT_SOURCE_INFO() \  
  25.     _tprintf(_T("File: %s, Line: %d, Date: %s, Time: %s, Timestamp: %s\n"), \  
  26.              _T(__FILE__), __LINE__, _T(__DATE__), _T(__TIME__), _T(__TIMESTAMP__));  

MacroTest.h 中定义函数 PrintSourceInfo() 和 PRINT_SOURCE_INFO(),在 MacroTest.cpp include=> MacroTest.h,并调用它们

输出结果

(1). 使用函数 PrintSourceInfo(),无论 Debug/Release 方式编译,无论是否 inline 化 PrintSourceInfo(),输出结果相同,均是 MacroTest.h 的信息:

File: d:\source\macrotest\macrotest.h, Line: 64, Date: Aug 28 2011, Time: 06:43:59, Timestamp: Sun Aug 28 06:43:57 2011, ANSI/ISO C: NO, C++: YES

(2). 使用宏 PRINT_SOURCE_INFO(),Debug/Release 方式编译输出结果大致相同,均是 MacroTest.cpp 的信息,只是 Debug 输出的 __FILE__ 是全路径,而 Release 输出的是相对路径:

File: d:\source\macrotest\macrotest.cpp, Line: 14, Date: Aug 28 2011, Time: 07:42:30, Timestamp: Sun Aug 28 07:38:25 2011

说明

(1). __FILE__、__DATE__、__TIME__ 是 char 字符串,而不是 wchar_t 宽字符字符串,需配合 _T()、_t 系列函数使用

(2). 如果在函数 PrintSourceInfo() 中使用宏,则 __FILE__、__LINE__、__TIME__ 等表示的是 PrintSourceInfo() 所在文件,即例 1 中的 MacroTest.h 的信息;如果在宏 PRINT_SOURCE_INFO() 中使用宏,因为宏 PRINT_SOURCE_INFO() 嵌套展开的缘故,__FILE__ 等表示的是 PRINT_SOURCE_INFO() 展开所在文件,即 MacroTest.cpp 的信息

(3). 无论使用 PrintSourceInfo() 还是 PRINT_SOURCE_INFO(),__LINE__ 总是文件 .h/.cpp 的固有行号,而非 [MacroTest.cpp include=> MacroTest.h] 预处理展开后的行号

(4). 在 VC 2005 中,上述编译方式下没有定义 __STDC__,要使 __STDC__ = 1,应同时满足以下条件:

  • (a). 以 C 方式编译
  • (b). 使用编译选项 /Za,表示禁止 Microsoft C/C++ 语言扩展,从而兼容 ANSI C/C++

C/C++ 预定义宏用途:诊断与调试输出^

参考 VC CRT 和 MFC 的代码,注意:需要在宏中使用 __FILE__、__LINE__,原因见上面“说明 (2)”

CRT 的诊断与调试输出:assert, _ASSERT/_ASSERTE, _RPTn/_RPTFn/_RPTWn/_RPTFWn^

CRT 的诊断宏 assert()、_ASSERT()/_ASSERTE()

  1. // assert.h  
  2.   
  3. _CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message, __in_z const wchar_t *_File, __in unsigned _Line);  
  4.   
  5. #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )  
  6.   
  7. // crtdbg.h  
  8.   
  9. #define _ASSERT_EXPR(expr, msg) \  
  10.         (void) ((!!(expr)) || \  
  11.                 (1 != _CrtDbgReportW(_CRT_ASSERT, _CRT_WIDE(__FILE__), __LINE__, NULL, msg)) || \  
  12.                 (_CrtDbgBreak(), 0))  
  13.   
  14. #ifndef _ASSERT  
  15. #define _ASSERT(expr)   _ASSERT_EXPR((expr), NULL)  
  16. #endif  
  17.   
  18. #ifndef _ASSERTE  
  19. #define _ASSERTE(expr)  _ASSERT_EXPR((expr), _CRT_WIDE(#expr))  
  20. #endif  

CRT 的调试输出宏 _RPTn()/_RPTFn(),n: 0 ~ 5
_RPTWn()/_RPTFWn() 是宽字符版

  1. // crtdbg.h  
  2.   
  3. #define _RPT_BASE(args) \  
  4.         (void) ((1 != _CrtDbgReport args) || \  
  5.                 (_CrtDbgBreak(), 0))  
  6.   
  7. #define _RPTF0(rptno, msg) \  
  8.         _RPT_BASE((rptno, __FILE__, __LINE__, NULL, "%s", msg))  

MFC 的诊断与调试输出:ASSERT/VERIFY, ASSERT_VALID, TRACE/TRACEn^

MFC 的诊断宏 ASSERT()/VERIFY()、ASSERT_VALID()

  1. // afx.h  
  2.   
  3. #define ASSERT(f)          DEBUG_ONLY((void) ((f) || !::AfxAssertFailedLine(THIS_FILE, __LINE__) || (AfxDebugBreak(), 0)))  
  4. #define ASSERT_VALID(pOb)  DEBUG_ONLY((::AfxAssertValidObject(pOb, THIS_FILE, __LINE__)))  

MFC 的调试输出宏 TRACE()/TRACEn(),n: 0 ~ 3

抱歉!评论已关闭.