如何在 C/C++ 中将断言放入发布版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/620892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:18:29  来源:igfitidea点击:

How to put assert into release builds in C/C++

c++creleaseassert

提问by Michael Burr

I need to only run ship build and I need to assert on certain condition in release build to see if the problem is fixed. How do I do it?

我只需要运行 ship build 并且我需要在 release build 中的某些条件下断言以查看问题是否已解决。我该怎么做?

回答by Michael Burr

Undefine the NDEBUG macro - you can do this locally around the asserts you want to remain in the build:

取消定义 NDEBUG 宏 - 您可以围绕要保留在构建中的断言在本地执行此操作:

#undef NDEBUG
#include <assert.h>   // reinclude the header to update the definition of assert()

or do whatever you need to do so your build process does not define the NDEBUG macro in the first place.

或者做任何你需要做的事情,这样你的构建过程就不会首先定义 NDEBUG 宏。

回答by Baiyan Huang

Why not just define your own assert:

为什么不定义你自己的断言:

#define assert(x) MessageBox(...);

回答by Daniel Daranas

Just call directly the part of the assertmacro definition that is active in release mode.

只需直接调用assert在发布模式下处于活动状态的宏定义部分。

You can find very useful definitions for assertions in C++ in this great article by Miro Samek(PDF). Then you can tweak them a bit to satisfy your needs. For example, you might create another macro, release_assert, that does the same as assert but regardless of whether it's in release or debug mode.

您可以在Miro Samek 的这篇精彩文章( PDF) 中找到对 C++ 中的断言非常有用的定义。然后您可以稍微调整它们以满足您的需求。例如,您可以创建另一个宏,release_assert,它的作用与 assert 相同,但不管它是处于发布模式还是调试模式。

回答by LeopardSkinPillBoxHat

The default behaviour of ASSERT is to abort the program under the Debug configuration, but this generally becomes a no-op under a Release configuration. I believe it does this by checking for the existence of the preprocessor NDEBUG macro. I'm not at work at the moment so cannot check this.

ASSERT 的默认行为是在 Debug 配置下中止程序,但这通常在 Release 配置下变为 no-op。我相信它是通过检查预处理器 NDEBUG 宏的存在来实现的。我现在不在工作所以无法检查这个。

I think the easiest way around this is to modify the Debug configuration to turn all optimisations up to the same level as Release (O2 from memory), and then re-build your software. This will give you the equivalent performance and speed of a Release build, but it will still define the NDEBUG preprocessor macro which means all failed ASSERTs will still cause the program to abort. Just remember to change the optimisation level back later, otherwise you will have trouble debugging under the Debug configuration.

我认为解决此问题的最简单方法是修改 Debug 配置,将所有优化提升到与 Release 相同的级别(来自内存的 O2),然后重新构建您的软件。这将为您提供与 Release 版本相同的性能和速度,但它仍将定义 NDEBUG 预处理器宏,这意味着所有失败的 ASSERT 仍将导致程序中止。以后记得把优化级别改回来,不然在Debug配置下调试会很麻烦。

In general though, ASSERTs should only be used for programming preconditions and never to handle failures in shipping software. You want to fail quicklyduring development, but gracefullyin front of a user.

但是,一般来说,ASSERT 应该只用于编程前提条件,而绝不能用于处理交付软件中的故障。您希望在开发过程中快速失败,但在用户面前优雅地失败。

回答by Zan Lynx

I like to define it to throw some sort of assert_exception derived from a std::runtime_error. Then catch it somewhere and do something useful.

我喜欢将它定义为抛出某种源自 std::runtime_error 的 assert_exception。然后在某个地方抓住它并做一些有用的事情。

回答by Tobias Langner

Actually - I'd go with shipping the debug version if you can live with it. If you don't need the performance of the release version, use the debug. It tend's to have fewer bugs (this is a gross oversimplification and if you program is free of bugs, just switching to release does not change this, but due to things the compiler does in debug mode, the bugs may not occur and/or have less severe consequences).

实际上 - 如果你能忍受它,我会去发送调试版本。如果不需要发布版本的性能,请使用调试。它往往有更少的错误(这是一个严重的过度简化,如果你的程序没有错误,只是切换到发布不会改变这一点,但由于编译器在调试模式下所做的事情,错误可能不会发生和/或有后果较轻)。

Perhaps it is also possible to optimize only the time critical parts of you program.

也许也可以只优化程序的时间关键部分。

It can also simplify debugging.

它还可以简化调试。

回答by Marco Kinski

When using Visual Studio you can undefine the NDEBUG precompiler definition to active asserts in the Release build.

使用 Visual Studio 时,您可以将 NDEBUG 预编译器定义取消定义为发布版本中的活动断言。

For example you can set $(undefesTheNDEBUG) in your Projekt settings for the /U option and then define the environment variable undefesTheNDEBUG to NDEBUG (SET undefesTheNDEBUG=NDEBUG) or pass it along with msbuild (/p:undefesTheNDEBUG=NDEBUG)

例如,您可以在 Projekt 设置中为 /U 选项设置 $(undefesTheNDEBUG),然后将环境变量 undefesTheNDEBUG 定义为 NDEBUG (SET undefesTheNDEBUG=NDEBUG) 或将其与 msbuild (/p:undefesTheNDEBUG=NDEBUG) 一起传递