c – 摆脱#ifndef NDEBUG

前端之家收集整理的这篇文章主要介绍了c – 摆脱#ifndef NDEBUG前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的大多数类都有调试变量,这使得它们经常看起来像这样:
class A
{
    // stuff
#ifndef NDEBUG
    int check = 0;
#endif
};

并且方法可能如下所示:

for (/* big loop */) {
    // code
#ifndef NDEBUG
    check += x;
#endif
}

assert(check == 100);

几乎没有什么比所有这些#ifndef NDEBUG的东西更糟糕.不幸的是没有编译器我知道可以优化检查变量没有这些#ifndefs(我不知道是否甚至允许).

所以我试图想出一个可以使我的生活更轻松的解决方案.以下是现在的样子:

#ifndef NDEBUG

#define DEBUG_VAR(T) T

#else

template <typename T>
struct nullclass {
    inline void operator+=(const T&) const {}
    inline const nullclass<T>& operator+(const T&) const { return *this; }
    // more no-op operators...
};

#define DEBUG_VAR(T) nullclass<T>

#endif

所以在调试模式下,DEBUG_VAR(T)只会产生一个T.否则,它使一个“空类”只有无操作.我的代码将如下所示:

class A {
   // stuff
   DEBUG_VAR(int) check;
};

然后我可以使用检查,就像它是一个正常的变量!真棒!但是,还有两个问题我无法解决

它只适用于int,float等

“null”类没有push_back()等.没有biggie.大多数调试变量都是int.

“空类”是1个字宽!

C中的每个类都至少为1个char.所以即使在释放模式下,使用N个调试变量的类将至少为N个字符太大.这在我眼里是不能接受的.这是我尽可能追求的零开销原则.

那么,如何解决这个第二个问题呢?在非调试模式下,甚至可以摆脱#ifndef NDEBUG而不伤害性能?我接受任何好的解决方案,即使它是你最黑暗的C魔法或C 0x.

解决方法

怎么样:
#ifndef NDEBUG
#define DEBUG_VAR(T) static nullclass<T>
#endif

现在,没有额外的存储被添加到使用DEBUG_VAR(T)作为成员的类,但声明的标识符仍然可以被使用,就像它是一个成员一样.

猜你在找的C&C++相关文章