我曾经在一家公司工作,其中一些主要架构师/开发人员已经强制要求断言不使用的各种项目,并且他们通常会从代码中删除并替换为异常.
我觉得他们在编写正确的代码时非常重要.任何人都可以建议如何证明这样的授权是合理的吗?如果是这样,断言有什么问题?
根据JaredPar的评论,我们使用assert的修改版本,就像合同一样.此版本已编译到发行版代码中,因此开销较小,但除非设置了诊断开关,否则将禁用,从而最大限度地降低性能开销.我们在此实例中的断言处理程序可以设置为禁用,静默模式(例如,记录到文件)或噪声模式(例如,在屏幕上显示abort/ignore,其中abort抛出异常).
我们使用自动回归测试作为我们的预发布测试的一部分,并且断言在这里非常重要,因为它们允许我们找到在GUI级别无法获取的潜在内部错误,并且在用户级别可能不是最初致命的.通过自动化,我们可以使用和不使用诊断运行测试,除了执行时间之外几乎没有开销,因此我们还可以确定断言是否有任何其他副作用.
关于断言要注意的一件事是副作用.例如,您可能会看到类似assert(MyDatabasesIsOk())的内容,这会无意中更正数据库中的错误.这是一个错误,因为断言永远不会改变正在运行的应用程序的状态.
关于断言,我唯一可以说的非常消极的是它们不会在零售代码中运行.在我们的团队中,我们倾向于避免断言.相反,我们使用契约,这是在零售和调试中运行的断言.
我们现在唯一一次使用断言是否满足以下条件之一.
断言代码有noticable性能的影响
特殊情况并非致命
偶尔会有一段代码可能会死亡,也可能不会死亡.我们将添加一个断言,基本上说"你是怎么来到这里的".不解雇并不意味着代码确实已经死了但是如果QA给我发电子邮件并说"这个断言意味着什么",我们现在有一个repro来获取特定的代码(当然会立即记录).
断言和异常用于两个不同的事情.
断言用于永远不会发生的状态.例如,signalton指针永远不应为null,并且应该在开发期间使用assert拾取此错误.处理它有一个例外是没有更多的工作.
另一方面,异常用于可能在应用程序的正常运行中发生的罕见状态.例如,使用fopen并返回一个空指针.它可能会发生,但大多数时候它会返回一个有效的指针.
使用断言是错误的,也不是正确的,但它归结为个人偏好,因为在一天结束时,它是一种使编程更容易并且可以被其他工具取代的工具.