变长参数的 Tracer

原创 2004年04月29日 22:15:00

几天前,在CSDN论坛看到这么一则讨论:在宏定义中怎么使用可变参数?(http://expert.csdn.net/Expert/topic/2925/2925165.xml)。楼主希望能定义这样的macro:

#define fun1(a, b, ...)   fun2(__FILE__, __LINE__, a, b, ...)

我猜楼主是想写trace,如果不能使用可变参数的macro,那么就得像MFC那样写一堆TRACE macros:


// 取自 MFC 7.1 的 afx.h
// The following trace macros are provided for backward compatiblity
//  (they also take a fixed number of parameters which provides
//   some amount of extra error checking)
#define TRACE0(sz)               TRACE(_T("%s"), _T(sz))
#define TRACE1(sz, p1)           TRACE(_T(sz), p1)
#define TRACE2(sz, p1, p2)       TRACE(_T(sz), p1, p2)
#define TRACE3(sz, p1, p2, p3)   TRACE(_T(sz), p1, p2, p3)

太丑陋了!还好,C99标准支持Variadic Macros,在GCC中,可以这么写:

// http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html
#define debug(format, ...)  fprintf(stderr, format, __VA_ARGS__)

还可以顺便打印文件名和行号:

#define debug(format, ...)  do {/
                fprintf(stderr, "%s (%d): ", __FILE__, __LINE__);/
                fprintf(stderr, format, __VA_ARGS__);/
                } while (0)

但可惜Visual C++ 7.1还不支持这项功能:( 不过我们在C++中至少可以绕弯解决,做到既能自动记录文件名和行号,又能使用变长参数调用。这个办法不是我独创的,实际上ATL的atltrace.h中就有它的实现(CtraceFileAndLineInfo class),我在Code Project也找到了相同的实现(http://www.codeproject.com/debug/location_trace.asp),甚至在CUJ的C++ Experts Forum 也能看到相近的做法(http://www.cuj.com/documents/s=8250/cujcexp2106alexandr/),当然Alexandrescu的办法技巧性更强。

思路:写一个重载了 operator() 的class,令 TRACE 宏返回该class的一个object:

#include
#include

#ifndef NDEBUG  // debug mode

class tracer
{
public:
  tracer(const char* file, int line)
    : file_(file), line_(line)
  {}
 
  void operator()(const char* fmt, ...)
  {
    va_list ap;
   
    // print the file name and line number
    fprintf(stderr, "%s (%d): ", file_, line_);
   
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
   
    fprintf(stderr, "/r/n"); // print the new-line character
  }

private:
  // copy-ctor and operator=
  tracer(const tracer&);
  tracer& operator=(const tracer&);

private:
  const char* file_;
  int         line_;
};
#define TRACE (tracer(__FILE__, __LINE__))
#else  // NDEBUG
#define TRACE (void)
#endif // NDEBUG

int main()
{
#ifndef NDEBUG
  tracer(__FILE__, __LINE__)("%x", 123);
#endif

  TRACE("%s", "Happy debugging.");
}

这样做是multithreading-safe的。G++ 3.3.1 / Visual C++ 7.1 / Borland C++ 5.5.1 通过。

构建简易网络与网络设备的简单配置(Cisco Packet Tracer)第一弹:交换机VLAN配置

配置简单的网络,作为网络实验课的内容,虽然很简单,我觉得也是有必要把它写下来的(况且实验报告册还没写呢)。这也就当做实验报告的前奏了... 对网络以及交换机的配置都是在思科的Cisco P...
  • u013009839
  • u013009839
  • 2015年06月25日 09:35
  • 2888

强大的网页性能测试工具--Speed Tracer

Speed Tracer由google开发的一款测试网页性能分析插件  (IE下推荐dynaTrace),包含: * Javascript parsing and execution * Layou...
  • zxxSsdsd
  • zxxSsdsd
  • 2015年10月26日 11:21
  • 1674

利用Cisco Packet Tracer仿真配置网络

1.设计目标  设计如图所示的网络,并进行IP配置    路由器的每个端口对应一个子网;要求的子网地址为:xx.yy.zz.0—xx.yy.zz+6.0(假设同学学号为xxyyzz),终...
  • yxq_fxd
  • yxq_fxd
  • 2016年05月21日 15:38
  • 3740

某公司网络拓扑设计——基于cisco packet tracer的使用

项目要求 1、 公司共约40 名员工,每人一台电脑。公司内有行政部、市场部、开发部和客户服 务部四个部门,其中开发部有员工15 名,市场部和客户服务部各有员工10 名,行政部 员工5 名。  2 、公...
  • u011616965
  • u011616965
  • 2014年02月23日 20:56
  • 2884

构建简易网络与网络设备的简单配置(Cisco Packet Tracer)第二弹:静态路由协议配置

本篇文章讲述了在路由器上配置静态路由的方法。 所谓静态路由,就是是指由用户或网络管理员手工配置的路由信息。当网络的拓扑结构或链路的状态发生变化时,网络管理员需要手工去修改路由表中相关的静态路由信息。静...
  • u013009839
  • u013009839
  • 2015年06月26日 10:43
  • 3752

Cisco Packet Tracer入门实验之双机互联

首先说明一下,笔者也是初学者,鉴于
  • gsls200808
  • gsls200808
  • 2014年10月23日 16:35
  • 1635

基于Cisco Packet Tracer的基础命令操作及组网实验

基于思科模拟器的基本命令操作及简单组网实验
  • R_g_Luo
  • R_g_Luo
  • 2017年07月04日 15:34
  • 1950

Android中用OpenGL ES Tracer分析绘制过程

Tracer for OpenGL ES(http://developer.android.com/tools/help/gltracer.html)是Android SDK中新增加的开发工具,可逐帧...
  • pizi0475
  • pizi0475
  • 2016年02月22日 10:34
  • 1191

Cisco Packet Tracer 配置网络实例---包括单臂路由-3层交换机-NAT的配置

说明:
  • u012922284
  • u012922284
  • 2014年04月11日 13:22
  • 4888

基于Packet tracer 的计算机网络实验第三节(DNS搭建与FTP管窥)

基于Packet tracer 的计算机网络实验第三节(DNS搭建与FTP管窥)【思科网络工程师培训,互联网最全认证资料】     之前的第一节中实际上涉及DNS配置,但是较为简单,并不能体现域名解析...
  • Outp0st
  • Outp0st
  • 2017年06月22日 01:57
  • 514
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:变长参数的 Tracer
举报原因:
原因补充:

(最多只允许输入30个字)