我只需要运行 ship build 并且我需要在 release build 中的某些条件下断言以查看问题是否已解决。我该怎么做?
7 回答
取消定义 NDEBUG 宏 - 您可以围绕要保留在构建中的断言在本地执行此操作:
#undef NDEBUG
#include <assert.h> // reinclude the header to update the definition of assert()
或者做任何你需要做的事情,这样你的构建过程就不会首先定义 NDEBUG 宏。
为什么不定义自己的断言:
#define assert(x) MessageBox(...);
只需直接调用assert
在发布模式下处于活动状态的宏定义部分。
您可以在Miro Samek 撰写的这篇精彩文章( PDF )中找到非常有用的 C++ 断言定义。然后,您可以稍微调整它们以满足您的需求。例如,您可以创建另一个宏,release_assert
它与 assert 的作用相同,但不管它是处于发布模式还是调试模式。
ASSERT 的默认行为是在 Debug 配置下中止程序,但这通常在 Release 配置下变成无操作。我相信它通过检查预处理器 NDEBUG 宏的存在来做到这一点。我现在不在工作,所以无法检查。
我认为解决此问题的最简单方法是修改调试配置以将所有优化提升到与发布(内存中的 O2)相同的级别,然后重新构建您的软件。这将为您提供与发布版本相同的性能和速度,但它仍将定义 NDEBUG 预处理器宏,这意味着所有失败的 ASSERT 仍将导致程序中止。请记住稍后将优化级别更改回来,否则您将无法在 Debug 配置下进行调试。
但总的来说,ASSERT 应该只用于编程前提条件,而不是处理交付软件中的故障。您希望在开发过程中快速失败,但在用户面前优雅地失败。
我喜欢将它定义为抛出某种从 std::runtime_error 派生的 assert_exception。然后在某个地方抓住它并做一些有用的事情。
使用 Visual Studio 时,您可以将 NDEBUG 预编译器定义取消定义为发布版本中的活动断言。
例如,您可以在 Projekt 设置中为 /U 选项设置 $(undefesTheNDEBUG),然后将环境变量 undefesTheNDEBUG 定义为 NDEBUG (SET undefesTheNDEBUG=NDEBUG) 或将其与 msbuild 一起传递 (/p:undefesTheNDEBUG=NDEBUG)
实际上 - 如果你能接受它,我会发布调试版本。如果不需要发布版本的性能,请使用调试。它往往有更少的错误(这是一个严重的过度简化,如果你的程序没有错误,只是切换到发布不会改变这一点,但由于编译器在调试模式下所做的事情,错误可能不会发生和/或有后果较轻)。
也许也可以只优化程序的时间关键部分。
它还可以简化调试。