为什么断言是从生产构建中编译出来的(性能除外)?

时间:2010-02-01 03:35:11

标签: error-handling assert

从生产代码中删除断言的典型理由是性能。这对我来说没有意义。是的,从性能至关重要的5%左右的代码中删除一些断言可能是一个有用的优化。但是对于其他95%,它们可能没有可衡量的影响,并且断言只会增加这样的可能性:如果您的代码有错误,它将快速失败并且易于诊断。

我在D中完成了大部分编程,它具有enforce()函数,基本上完成assert()所做的功能,除了它保留在发布版本中。我通常发现自己大部分时间都在使用enforce()assert()只在enforce()过于昂贵的地方使用{。}}。

除了性能之外是否还有其他原因可以从发布版本中删除断言?如果没有,为什么语言不能使断言的默认行为即使在发布版本中也始终执行,并提供更冗长,更难记忆的第二个函数,例如expensiveAssert()从发布版本中剥离出来的函数建议仅在代码的性能关键部分使用它?

4 个答案:

答案 0 :(得分:3)

我认为assert()首先是一个纯粹的开发工具。

最终用户的软件应提供某种错误处理(通过记录和/或向用户显示消息)。 assert()不提供错误处理。

但是,我通常使用自己的发布和调试断言函数。发布和调试断言仅用于异常错误 - 这种情况永远不会发生。但是它们提供了一个有用的错误消息(对开发人员很有用,通常对最终用户没那么有用)。

显式处理可能发生的错误(输入/输出,错误配置,......)并向用户发送消息。

答案 1 :(得分:2)

不只是这样。我认为在生产版本中保留断言会增加人们对于文本(和/或源代码片段)最终出现在二进制文件中的偏执(想想如果他们最终发布的二进制文件会有什么代码注释!),这反过来会不鼓励使用断言。

您的里程可能会有所不同。

答案 2 :(得分:2)

我的回答是,断言会过早地中止程序的执行,通常是在没有必要时。虽然一个人可能是偏执狂,因为跳过的断言会导致行为不确定,但程序可能无论如何都会跛行。当你作为用户遇到断言时,断言可能会非常烦人和愚蠢。因为,为什么这个游戏不能处理一个无效的纹理?!!

尽管断言是开发时快速捕获错误的好方法,但用户讨厌它们(在我看来)。

答案 3 :(得分:1)

我认为在生产代码中使用断言是可以的。禁用它会让您失去对生产中系统中的问题的一些见解。而且我总是对我的程序/系统表现如何+生产失败感兴趣。在我看来,改进系统的最佳“测试数据”通常来自真实用户。

我更喜欢的是:

  • 在生产代码中保留断言
  • 在断言失败的情况下记录好信息
  • 处理断言错误( - >永远不会向用户显示堆栈跟踪)
  • 经过一段时间的屏幕日志文件断言失败并修复你的代码(对我来说断言是编程或合同违规错误触发器)