Loading

1 预定义宏是什么

为了方便处理一些有用信息,C/C++编译器中的预处理器会定义一些预处理标识符,也就是预定义宏。这些宏定义不仅可以帮助完成源码的跨平台编译,灵活使用也可以巧妙地输出非常有用的调试信息,其具有以下特点:

  • 预定义宏的名称都是以“__”(两条下划线)开头和结尾的,并且通常由大写字符组成
  • 预定义宏不能被取消定义(#undef)或被编程人员重新定义
  • 使用预定义宏需要包含头文件<stdio.h>

2 常用的预定义宏

下表列举了一些在C/C++编程中常用的预定义宏:

预定义宏含义
__DATE__源文件的编译日期,以“Mmm dd yyy”形式的字符串常量表示
__TIME__源文件的编译时间,以“hh:mm:ss”形式的字符串常量表示
__TIMESTAMP__源文件的编译时间戳,以字符串常量表示
__FILE__源文件的名称,以字符串常量表示
__LINE__源文件中正被编译的行号,以十进制整型常量表示
__VERSION__编译器的版本,以字符串常量表示
__STDC__若当前编译器严格遵循 ANSI C 标准,则该宏值为1,否则未定义
__STDC_VERSION__若编译器标准符合C89,该宏值为199409L;
若编译器标准符合C99,该宏值为199901L;
若编译器标准符合C11,该宏值为201112L
__FUNCTION__其展开为当前函数名,以字符串常量表示(函数作用域)

3 预定义宏的用例

3.1 确定程序的编译时间

利用“__DATE__”和“__TIME__”预定义宏可以确定程序的编译时间,示例代码如下:

int main (void)
{
    printf("www.nixinglong.com\n");  // N1XON's personal website
    printf("Compiled on %s at %s\n", __DATE__,__TIME__);
    return 0;
}

3.2 兼容不同版本的编译器

利用“__STDC__”与“__STDC_VERSION__”预定义宏可以编写兼容不同版本编译器的程序,示例代码如下:

#ifdef __STDC__
/* Some version of standard C */
#if defined(__STDC__VERSION__)&&__STDC_VERSION__>=199901L
/* C99 */
#elif defined(__STDC_VERSION__)&&__STDC_VERSION__>=199409L
/* C89 and amendment 1 */
#else
/* C89 but not amendment 1*/
#endif
#else /* __STDC__not defined */
/*Not Standard C*/
#endif

3.3 异常跟踪

利用”__FILE__”、”__LINE__”与”__FUNCTION__”预定义宏,可以方便的在调试程序时对程序运行异常进行跟踪,示例代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define MESSAGE(message,assertion) \
          do{\
               if(!(assertion)){\
                    printf("line %d in %s(%s)", __LINE__, __FILE__,__FUNCTION__);\
                       if(message){\
                            printf(":%s",message);\
                          }\
                          printf("\n");\
                          abort();\
                 }\
             }while(0)
int OpenFile(const char *filename)
{
    int fd;
    MESSAGE("文件名称不能够为空",filename);
    MESSAGE("文件不存在",0==access(filename,F_OK));
    fd = open(filename,O_RDONLY);
    close(fd);
    return 0;
}

int main(int argc,char **argv)
{
    MESSAGE("命令参数不能够为空",argc==2);
    OpenFile(argv[1]);
    return 0;
}


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

👤本站访客数: 👁️本站访问量: