__FILE__,__LINE__

来源:互联网 发布:泛海三江消防主机编程 编辑:程序博客网 时间:2024/04/25 00:48

前言:

我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除,而一旦需要再次调试的时候,这些语句又不得不一条条的加上,这给我们带来了很大的不便,浪费了我们很多的时间,也造成了调试的效率低下。所以,很多人会选择使用宏定义的方式来输出调试语句。

比如,定义一个宏开关:

#define __DEBUG

当需要调试的时候,使用语句:

#ifdef __DEBUG

printf(xxx);

#endif

这种方式的调试,可以通过undef __DEBUG的方式让告知编译器不编译这些语句,从而不再输出这些语句。但是这种方式的麻烦之处也是显而易见的,每一条调试语句都需要使用两条宏定义来包围,这不但在代码的编写上不便,源码结构也不好看,工作量依然不小。

如果我们能够把这三条语句编程一条,那该多舒服呀~,于是,我们想到使用这样的语句:

#ifdef __DEBUG

#define DEBUG(info)    printf(info)

#else

#define DEBUG(info)

#endif

这样,我们在编写代码的时候,使用DEBUG一条语句就可以了,我们把宏开关__DEBUG打开,所有的DEBUG(info)宏定义信息都会被替换为printf(info),关上则会被替换成空,因此不会被编译。嗯,这次方便多了,一条语句就可以了~~~ 但是,问题也随之而来了,printf是支持多个参数的,而且是不定参数,当你使用下面这样的语句时就会报错:

DEBUG("%s",msg)

这是因为,DEBUG(info)这条宏定义只支持一个参数的替换。

因此,我们希望DEBUG能够像printf那样,支持多个参数,并且这些参数刚好展开成为printf语句本身使用的参数,譬如:我们希望DEBUG("%s",msg)能够展开为printf("%s",msg)

正文:

通过网上的资料查阅,发现自C99规范以后,编译器就开始支持不定参数的宏定义,就像printf一样。

大家可以看看这篇文章:http://blog.csdn.net/aobai219/archive/2010/12/22/6092292.aspx

(这个链接也转的,我已经找不到原始作者到底是谁了,唉,互联网啊。。。)

于是,我们定义了一个这样的东东:

#define DEBUG(format, ...) printf (format, ##__VA_ARGS__)(' ## '的意思是,如果可变参数被忽略或为空,将使预处理器( preprocessor )去除掉它前面的那个逗号。)

于是乎,我们神奇地发现,DEBUG完全取代了printf,所有的DEBUG(…)都被完成的替换成了printf(…),再也不会因那个可恶的逗号而烦恼了。

但是,我们发现,光有printf还不够,虽然调试信息是输出了,可是很多的调试信息输出,我们并不能一下子知道这条信息到底是在那里打印出来的,于是,我们又想,能不能把当前所在文件名和源码行位置也打印出来呢,这样不就一目了然了吗,哪里还用的着去想,去找调试信息在哪里输出的呢,都已经打印出来了!

于是我们就有了下面的故事。。。

编译器内置宏:

先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息。

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

__DATE__:在源文件中插入当前的编译日期

__TIME__:在源文件中插入当前编译时间;

__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

编译器在进行源码编译的时候,会自动将这些宏替换为相应内容。

看到这里,你的眼睛应该一亮了吧,嗯,是的,__FILE__和__LINE__正是我们前面想要的输出的,于是,我们的每一条语句都变成了:

DEBUG("FILE: %s, LINE: %d…",__FILE__,__LINE__,…)

其实没有必要,__FILE__本身就会被编译器置换为字符常量,于是乎我们的语句又变成了这样:

DEBUG("FILE:"__FILE__", LINE: %d…",__LINE__,…)

但是,我们还是不满足,依然发现,还是很讨厌,为什么每条语句都要写"FILE:"__FILE__", LINE: %d 以及,__LINE,这两个部分呢?这不是浪费我们时间么?

哈哈,是的,这就是本次大结局,把DEBUG写成这样:

DEBUG(format,...) printf("FILE: "__FILE__", LINE: %d: "format"/n", __LINE__, ##__VA_ARGS__)

没错,就是这样!下面,所有的DEBUG信息都会按照这样的方式输出:

FILE: xxx, LINE: xxx, …….

最后:

最后,老规矩,coding测试。

 

  1. //============================================================================  
  2. // Name : debug.cpp  
  3. // Author : boyce  
  4. // Version : 1.0  
  5. // Copyright : pku  
  6. // Description : Hello World in C++, Ansi-style  
  7. //============================================================================  
  8. #include  
  9. #define __DEBUG__  
  10. #ifdef __DEBUG__  
  11. #define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"/n", __LINE__, ##__VA_ARGS__)  
  12. #else  
  13. #define DEBUG(format,...)  
  14. #endif  
  15. int main() {  
  16.     char str[]="Hello World";  
  17.     DEBUG("A ha, check me: %s",str);  
  18.     return 0;  
  19. }  

 

 

测试结果:

是不是感觉很酷?O(∩_∩)O哈哈~



还可以通过语句#line来重新设定__LINE__的值,举例如下:
  1. #include <stdio.h>


  2. #line 200  //指定下一行的__LINE__为200
  3. main()
  4. {
  5. printf("%d\n",__LINE__);
  6. printf("%d\n",__LINE__);
  7. printf("%d\n",__LINE__);
  8. };
编译执行后输出结果为:
202
203
204

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

另外gcc还支持__func__,它指示所在的函数,但是这个关键字不被windows下的vc6.0支持,举例如下:
  1. #include <stdio.h>
  2. void main()
  3. {
  4. printf("this is print by function %s\n",__func__);
  5. }
其编译后输出结果为
this is print by function main




注意 “#line”、 “__LINE__”、 “__FILE__" 及 “__func__" 都是大小写敏感的。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 所学类别找不到音乐表演怎么办 公司口头通知不续签合同怎么办 雪纺衬衣皱了怎么办 狗打架受伤怎么办泰迪 大狗打架破了怎么办 舌头上长溃疡怎么办吃什么药 悠悠球不回弹怎么办啊 围棋遇到对方不停围堵怎么办? s围棋业余四段想提升怎么办 wps禁止创建分享链接怎么办 驾驶人开车违章不认可怎么办 京东白条退货分期服务费怎么办 新车年检标丢了怎么办 异地违章罚单丢了怎么办 异地现场违章罚单丢了怎么办 新车没有牌照过停车杆怎么办 驾照换证时间过了怎么办 杭州告知单丢了怎么办 电工证过了复审日期怎么办 大人有居住证小孩没有怎么办 异地补办身份证没有暂住证怎么办 挂科了心里难受怎么办 c1升b2考不过怎么办 b2驾照扣了1分怎么办 红绿色盲驾考怎么办 驾驶证忘带被交警查了怎么办 车子被扣45分怎么办 驾照被扣在外省交警支队怎么办 从渭南把驾照转到西安怎么办 a1a2驾驶证扣3分怎么办 车辆累计扣12分怎么办 驾照扣了40分怎么办 驾驶证扣了30分怎么办 b2驾照逾期未审怎么办 c1实习期扣6分怎么办 车子累计扣30分怎么办 实习期间扣满12分怎么办 新手驾照扣6分怎么办 a2驾驶证逾期未审验怎么办 c1驾照扣了6分怎么办 b1驾照被扣12分怎么办