加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 摆脱#ifndef NDEBUG

发布时间:2020-12-16 05:17:21 所属栏目:百科 来源:网络整理
导读:我的大多数类都有调试变量,这使得它们经常看起来像这样: class A{ // stuff#ifndef NDEBUG int check = 0;#endif}; 并且方法可能如下所示: for (/* big loop */) { // code#ifndef NDEBUG check += x;#endif}assert(check == 100); 几乎没有什么比所有这些
我的大多数类都有调试变量,这使得它们经常看起来像这样:
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)作为成员的类,但声明的标识符仍然可以被使用,就像它是一个成员一样.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读