- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我的大部分类都有调试变量,这使得它们通常看起来像这样:
class A
{
// stuff
#ifndef NDEBUG
int check = 0;
#endif
};
方法可能如下所示:
for (/* big loop */) {
// code
#ifndef NDEBUG
check += x;
#endif
}
assert(check == 100);
没有什么比所有这些#ifndef NDEBUG 更丑陋的了。不幸的是,我知道没有编译器可以在没有这些 #ifndef 的情况下优化 check 变量(我不知道这是否被允许)。
因此,我试图想出一个能让我的生活更轻松的解决方案。这是现在的样子:
#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模式下,DEBUG_VAR(T) 只是生成一个 T。否则它生成一个只有空操作的“空类”。我的代码看起来像这样:
class A {
// stuff
DEBUG_VAR(int) check;
};
然后我就可以像使用普通变量一样使用 check 了!惊人的!但是,还有2个问题我无法解决:
“空类”没有 push_back() 等。没什么大不了的。大多数调试变量无论如何都是整数。
C++ 中的每个类至少有 1 个字符宽。因此,即使在 Release模式下,使用 N 个调试变量的类也将至少有 N 个字符太大。这在我看来是不能接受的。这违背了我尽可能追求的零开销原则。
那么,我该如何解决第二个问题?是否有可能在不影响非 Debug模式下的性能的情况下摆脱#ifndef NDEBUG?我接受任何好的解决方案,即使它是您最黑暗的 C++ 巫术或 C++0x。
最佳答案
怎么样:
#ifndef NDEBUG
#define DEBUG_VAR(T) static nullclass<T>
#endif
现在没有额外的存储被添加到一个类中,其中 DEBUG_VAR(T)
被用作成员,但是声明的标识符仍然可以像成员一样使用。
关于c++ - 摆脱#ifndef NDEBUG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5017099/
所以基本上我有一个用 C 编写的程序,它由几个 .c 文件组成。它们的 makefile 如下所示: CC=gcc CFLAGS=-I. DEBUGFLAGS=-D NDEBUG -O3 defaul
在阅读了一些关于滥用异常的线程后(基本上是说如果函数前提条件不正确你不想展开堆栈 - 可能表示你所有的内存都已损坏或同样危险的东西)我正在考虑使用断言() 更频繁。以前我只使用 assert() 作为
C++ Primer 说 The behavior of assert depends on the status of a preprocessor variable named NDEBUG. W
考虑在 my_lib.a 和与 my_lib.a 链接的 my_prog 中编译的 C++ 头文件。该库是在没有 NDEBUG 的情况下编译的,而 my_prog - 有 NDEBUG。会导致 ODR
对于上面的例子,我试图弄清楚 increment 方法是否真的会被内联。如果在我定义 NDEBUG 标志时断言将被编译器删除,增量方法将变成单行,因此它被实际内联的可能性会增加。所以问题归结为删除断言
我想定义一个与标准 assert(3) 相同的 assert 宏除了在定义 NDEBUG 时它不会被预处理器删除外,调用其他情况。 这样的调用,让我们在这里称它为 assert2,例如,如果您希望在软
我的大部分类都有调试变量,这使得它们通常看起来像这样: class A { // stuff #ifndef NDEBUG int check = 0; #endif }; 方法可能如
我有相当大的一段代码,在开发版本中运行良好,代码中有许多 assert()。我使用传递给 g++ 的 -DNDEBUG 指令禁用了断言,现在我的代码因 seg 而中断。过错。关于 assert() 有
我在一篇文章中读到,放置以下预处理器行会忽略所有后续的断言预处理器指令。但这似乎不起作用,实际上 assert 语句由预处理器处理,并在不满足 assert 中的条件时中止程序(我知道当不满足 ass
应该使用哪个预处理器定义来指定代码的调试部分? 使用 #ifdef _DEBUG 或 #ifndef NDEBUG 或者有更好的方法,例如#define MY_DEBUG? 我认为 _DEBUG 是
我正在使用以下宏来打印我在网络上找到的调试信息。效果很好。但是,我想在调试调用函数 A 的函数 B 时关闭函数 A 的调试打印。我尝试了 #define NDEBUG function A #unde
Why does assert not work here? ^ 显然,Rcpp 有自己定义 NDEBUG 的习惯,即使不是我自己定义的。 m@m-X555LJ:~/wtfdir$ cat WTF.r
我正在审核一些使用 Qt 框架编写的源代码。典型的发布构建命令行输出包括 QT_NO_DEBUG 预处理器宏,但不包括 Posix 的 NDEBUG 预处理器宏。 Qt documentation o
当宏 NDEBUG 定义时,标准 C assert 宏被禁用,意思是“不调试”。这会导致非常糟糕的双重否定情况,例如 #ifndef NDEBUG//DebuggingCode #endif。似乎 R
我对各种平台/编译器(“实现”)/框架分配给 C 和 C++ 预处理器宏 NDEBUG 的用途感兴趣。 C和C++标准只提到过一次这个定义,即控制assert()宏的行为。 我会要求只包含具体的答案,
我读到有人担心过度使用 noexcept 可能会阻碍可测试的库。 考虑: T& vector::front() noexcept { assert(!empty()); //
当与 boost::serialization 链接时,我在项目的“发布”版本中遇到问题。我的“调试”和“发布”构建之间唯一真正的区别是我定义了 DEBUG 并在调试中使用了 -O0 并且我定义了 N
可以在我们的开发和生产应用程序的控制台中看到以下代码: #ifndef NDEBUG NSLog(@"log message"); #endif 谁能告诉我发布应用程序怎么可能?我们使用 Xc
如果我在 main.cpp 的顶部定义 NDEBUG,我会得到所有这些错误: 1> All outputs are up-to-date. 1>libcmt.lib(invarg.obj) : er
环境: $ g++ --version g++ (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0 众所周知,在包含 assert.h 之前定义的 NDEBUG 可以禁用用于调试的
我是一名优秀的程序员,十分优秀!