zoukankan      html  css  js  c++  java
  • 可变参数的宏

    调试的时候需要打印一些调试信息,刚开始的做法如下:
    1 #ifdef _DEBUG
    2 // 打印调试信息
    3 #endif

    这样的代码写得多了,就觉得繁琐,于是我进行了改进如下: 

    1 void DebugPrint(const char * format, ... );
    2 #ifdef _DEBUG
    3 #define DEBUG_PRINT DebugPrint
    4 #else
    5 #define DEBUG_PRINT 
    6 #endif

     这样就可以在调试模式下使用DEBUG_PRINT打印各种类型的数据。


    自鸣得意了一段时间,忽然想到了一个问题,在Release模式下,语句:
    1 DEBUG_PRINT("Hello, %s""World");

    会被扩展成如下:

    "Hello, %s", "World";

    虽然这样子不会影响到程序的运行,但是万一产生某些副作用呢???于是到网上搜了一下,找到了下面的解决方案:
    1 void DebugPrint(const char * format, ... );
    2 #ifdef _DEBUG
    3 #define DEBUG_PRINT DebugPrint
    4 #else
    5 #define DEBUG_PRINT /\
    6 / DebugPrint
    7 #endif
    这样子改好后,在Release模式下,这个宏会被展开为一个注释,完全消除了副作用。
    但是这种方法会用另外一个缺点,DEBUG_PRINT语句后面不能跟其他的可执行语句,否则在release模式下会被注释掉。

    这时候我就想啊,如果C提供可变参数的宏该多好啊,想到了这里,忽然想到C99似乎有对可变参数宏的支持,
    于是翻了一下书本,果然啊!

    C99下,使用可变参数宏的方式如下:
    一个例子,如下:
    1 #define MyMax(...) max(__VA_ARGS__)
    其中省略号(...)表示可变参数,和C函数的可变参数表示法一样;__VA_ARGS__决定了可变参数在何处被替换。
    对于语句:
    MyMax(a, b); 
    会被替换为:
    max(a, b);

    将之应用于我的需求,可以修改如下:
    1 void DebugPrint(const char * format, ... );
    2 #ifdef _DEBUG
    3 #define DEBUG_PRINT(format, ...) DebugPrint(format, __VA_ARGS__)
    4 #else
    5 #define DEBUG_PRINT(format, ...)  
    6 #endif
    现在好了,如果在release模式下,DEBUG_PRINT会被替换为空格,再也没有副作用了。

    针对C99的方式,我做了一下实验:
    在VC2008下运行良好,但是悲催的VC6却不支持,不过想想也是,VC6诞生的时候C99不知道还在哪呢!

  • 相关阅读:
    BUAA OO 2019 第三单元作业总结
    OpenJML入门
    BUAA OO 2019 第二单元作业总结
    BUAA OO 2019 第一单元作业总结
    Spring MVC原理
    Spring AOP原理
    Spring DI原理
    Spring IOC原理分析
    观察者模式
    装饰模式
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2494636.html
Copyright © 2011-2022 走看看