首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >摆脱#ifndef NDEBUG

摆脱#ifndef NDEBUG
EN

Stack Overflow用户
提问于 2011-02-16 13:36:11
回答 3查看 7.3K关注 0票数 10

我的大多数类都有调试变量,这使得它们通常如下所示:

代码语言:javascript
运行
复制
class A
{
    // stuff
#ifndef NDEBUG
    int check = 0;
#endif
};

方法可能如下所示:

代码语言:javascript
运行
复制
for (/* big loop */) {
    // code
#ifndef NDEBUG
    check += x;
#endif
}

assert(check == 100);

没有什么东西比那些#ifndef NDEBUG更丑了。不幸的是,我知道没有这些#ifndefs,没有编译器能够优化check变量(我不知道这是否被允许)。

所以我试着想出一个能让我的生活更轻松的解决方案。现在的情况如下:

代码语言:javascript
运行
复制
#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,否则它只生成一个"null类“而没有操作。我的代码看起来是这样的:

代码语言:javascript
运行
复制
class A {
   // stuff
   DEBUG_VAR(int) check;
};

然后,我可以使用检查,就好像它是一个正常的变量!太棒了!然而,仍有两个问题我无法解决:

1.它只适用于int、等。

"null类“没有push_back()等。无论如何,大多数调试变量都是ints。

2.“空类”的宽度为1个字符!!

C++中的每个类至少有一个字符宽。因此,即使在发布模式下,使用N个调试vars的类也至少是N个字符太大。这在我看来是无法接受的。这违背了我所追求的零开销原则。

那么,如何解决第二个问题呢?是否有可能在不影响性能的情况下摆脱#ifndef?我接受任何好的解决方案,即使这是你最黑暗的C++魔法或C++0x。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-16 13:43:09

不如:

代码语言:javascript
运行
复制
#ifndef NDEBUG
#define DEBUG_VAR(T) static nullclass<T>
#endif

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

票数 8
EN

Stack Overflow用户

发布于 2011-02-16 13:40:20

您无法解决第二个问题,因为c++标准要求类或对象的大小至少为一个字节。

最简单的解决方案是不引入此类黑客,并对代码进行适当的单元测试。

票数 8
EN

Stack Overflow用户

发布于 2011-02-16 13:56:08

在调试模式下声明成员对象静态如何:

代码语言:javascript
运行
复制
#define DEBUG_VAR(T) static nullclass<T>

您必须在某个地方定义每个对象的实例。

(顺便说一句,空类的对象必须占用空间的原因是它们可以有唯一的指针。)

编辑:删除第二个想法-不起作用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5017099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档