- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想定义一个与标准 assert(3)
相同的 assert
宏除了在定义 NDEBUG
时它不会被预处理器删除外,调用其他情况。
这样的调用,让我们在这里称它为 assert2
,例如,如果您希望在软件的发布版本中也进行一些检查,那么它很有用。
我怎样才能以合理便携的方式做到这一点?我总是可以完全重新创建 assert
机制,比如 1:
#define assert2(cond) cond ? (void)0 : die_now(#cond, __FILE__, __LINE__)
static die_now(char *cond_str, const char *file, int line) {
// print a message to stderr here
...
abort(); // or maybe abort ?
}
...但我更愿意使用与现有 assert 调用相同的机制。特别是,内置的 assert
调用可以做一些很好的事情,比如处理编译器和平台的所有各种怪异情况,用特殊的魔法注释断言条件,让编译器假设条件在调用后成立, pretty-print 函数名称,等等。
在包含 assert.h
之前,我可以通过 #undef NDEBUG
获得内置的 assert
- 但我看不到如何重命名它到 assert2
。我想我可以将系统头文件中 assert
的 definition 复制并粘贴到 #define assert2
行中,但这是 ( a) 可能违反某些许可或版权,以及 (b) 需要针对每个平台重复。
请不要开始争论这样的功能是否有用,或者它是否是实现更高层次目标的合理方法。我特别询问是否可以在不依赖 NDEBUG
的情况下以另一个名称重新使用现有的 assert
调用。
1 当然,将 die_now
声明为 static
函数并不理想,因为它会复制 die_now
在每个使用 as assert
的编译单元中运行(或者更糟,甚至可能是所有只包含 header 的编译单元),因此它实际上应该在其自己的复杂单元中定义为外联,但是这是使用此功能的另一个复杂因素。
最佳答案
我会以相反的方式来做:从不定义 NDEBUG
,所以 assert
总是启用的,并定义一个 assert2
这是assert
的空操作或别名。然后您可以随意打开和关闭 assert2
:
// Note: no include guard
//
// Copy NDEBUG to NDEBUG2
#undef NDEBUG2
#ifdef NDEBUG
#define NDEBUG2 1
#endif
#undef NDEBUG
/* include <assert.h>, so that assert and friends are defined
* assert.h also lacks an include guard, but multiple inclusions
* are required to be OK (section 7.1.2 paragraph 4, if you care.)
*/
#include <assert.h>
/* Now define an assert which respects the original NDEBUG */
#undef assert2
#ifdef NDEBUG2
#define assert2(x)
#else
#define assert2 assert
#endif
现在您可以通过在定义或取消定义 NDEBUG
后重新包含 "assert2.h"
来回翻转。上面的文件总是取消定义 NDEBUG 作为副作用,但你可以在最后从 NDEBUG2
将它复制回来。
关于c - 定义一个即使定义了 NDEBUG 也有效的断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42093734/
所以基本上我有一个用 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 可以禁用用于调试的
我是一名优秀的程序员,十分优秀!