简体   繁体   English

是否有可能使用零成本的assert()使得在调试和发行版本之间不必修改代码?

[英]Is it possible to have a zero-cost assert() such that code should not have to be modified between debug and release builds?

I've noticed that some code often looks like this: 我注意到一些代码通常看起来像这样:

#ifdef DEBUG
assert(i == 1);
#endif //DEBUG

and that you may have several blocks of these sitting around in your raw code. 并且您的原始代码中可能有几个代码块。 Having to write out each block is tedious and messy. 必须写出每个块是乏味且混乱的。

Would it be plausible to have a function like this: 具有这样的功能是否合理:

auto debug_assert = [](auto expr) { 
 #ifdef DEBUG
 assert(expr);
 #endif //DEBUG
};

or something like this: 或类似这样的东西:

#ifdef DEBUG
auto debug_assert = [](bool expr) {
  assert(expr);     
};
#else //DEBUG
void debug_assert(bool expr) {}
#endif //DEBUG

to get a zero-cost assert when the DEBUG flag is not specified? 未指定DEBUG标志时得到零成本的断言? (ie it should have the same effect as if it was not put into the code without the lambda running, etc. and be optimized out by the g++/clang compilers). (即,它应具有与未运行lambda的情况下未放入代码中的效果相同,并由g ++ / clang编译器进行优化)。

As mentioned by @KerrekSB, you can already disable asserts by defining NDEBUG before including <cassert> . 如@KerrekSB所述,您可以通过在包含<cassert>之前定义NDEBUG来禁用断言。 The best way to ensure that it's defined before including the header file is to list it in as the argument to the compiler (with gcc it's -DNDEBUG ) 确保在包含头文件之前已对其进行定义的最佳方法是将其作为编译器的参数列出(对于gcc来说是-DNDEBUG

Note: the assert is removed by replacing it with a no-op expression, and there, the argument isn't evaluated at all (which is different from your suggested solution)! 注: assert通过与无操作表达式来替换它删除,并那里所有的参数不计算(这是从你的建议的解决方案不同)! This is why it's of utmost importance to not call any functions that have side effects in assert . 这就是为什么最重要的是不要在assert调用任何有副作用的函数。

For completeness: here is how assert can be implemented: 为了完整性:这是assert实现方式:

#include <cstdio>
#include <cstdlib>

#ifndef NDEBUG
#define assert(EXPRESSION) ((EXPRESSION) ? (void)0 : (printf("assertion failed at line %d, file %s: %s\n", __LINE__, __FILE__, #EXPRESSION), exit(-1)))
#else
#define assert(EXPRESSION) (void)0
#endif

Introducing your own assert -style macro is very commonly done. 引入自己的assert -style宏非常常见。 There are quite a lot of reasons you may want to do this: 您可能有很多原因要这样做:

  • you want to include more information about the evaluated expression (see Catch's REQUIRE and how they use expression templates to decompose the expression into individual elements and stringify them) 您想要包括有关评估表达式的更多信息(请参阅Catch的REQUIRE以及它们如何使用表达式模板将表达式分解为单个元素并将其字符串化)
  • you want to do action other than exit() ing the program, like throwing an exception, mailing the developer, logging to a file, breaking into the debugger 除了exit()程序外,您还想执行其他操作,例如引发异常,向开发人员发送邮件,登录到文件,进入调试器
  • you want to evaluate the expression even on release builds which is less error prone than not evaluating it at all (after all, if it doesn't have side effects, it can be eliminated by a compiler optimizations, and if it does, you just avoided a heisenbug) 您甚至希望即使在发行版本上也要评估该表达式,而该版本比根本不评估它更不容易出错(毕竟,如果它没有副作用,则可以通过编译器优化来消除它,如果确实如此,则只需避免了heisenbug)
  • and so on, and so on (if you have an idea, you can post a comment, I'll add it to the answer) 等等,依此类推(如果您有想法,可以发表评论,我将其添加到答案中)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Qt Creator:单元测试:是否有可能有四种构建代码的方法(调试,发布,调试|发布和测试) - Qt Creator: unit-test: is it possible to have four ways of building a code (debug, release, debug|release and Test) 具有数据成员语法的零成本属性 - Zero-cost properties with data member syntax 不扔是零成本的时候,noexcept 没用吗? - Is noexcept useless when not throwing is zero-cost? 吸气剂的成本是否为零? - Does a getter have zero cost? 共享指针线程安全是零成本吗? - Is shared pointer thread-safety zero-cost? c ++中内联函数的零成本列表 - Zero-cost lists for inline functions in c++ 用于SoA / AoS内存布局的C ++零成本抽象 - C++ zero-cost abstraction for SoA/AoS memory layouts 发布和调试版本之间的时差 - Time differences between Release and Debug builds MS Visual C ++发行版和调试版本之间行为不同的可能原因 - Possible causes for different behavior between MS Visual C++ release and debug builds 我有一个发布二进制文件,没有使用gcc构建的调试信息,有源代码 - I have a release binary with no debug information build with gcc , have source code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM