c++ - 如何正确重写 ASSERT 代码以在 msvc 中传递/分析?

标签 c++ code-analysis visual-c++ assert

Visual Studio 为 C/C++ 添加了代码分析 (/analyze) 以帮助识别错误代码。这是一个非常好的功能,但是当您处理旧项目时,您可能会被警告的数量弄得不知所措。

大多数问题的产生是因为旧代码在方法或函数的开头执行一些断言。

我认为这是代码中使用的 ASSERT 定义(来自 afx.h)

#define ASSERT(f)          DEBUG_ONLY((void) ((f) || !::AfxAssertFailedLine(THIS_FILE, __LINE__) || (AfxDebugBreak(), 0)))

示例代码:

ASSERT(pBytes != NULL);
*pBytes = 0; // <- warning C6011: Dereferencing NULL pointer 'pBytes'

我正在寻找一种简单、干净和安全的解决方案来解决这些警告,但并不意味着禁用这些警告。我有没有提到当前代码库中有很多事件?

最佳答案

/analyze 不保证产生相关且正确的警告。 它可以而且将会遗漏很多问题,并且还会给出一些误报(它标识为警告的东西,但它们是绝对安全的,并且永远不会实际发生)

期望/analyze 的警告为零是不现实的。

它指出了一种情况,您取消引用了一个无法验证的指针是否始终有效。据 PREfast 所知,不能保证它永远不会为 NULL。

但这并不意味着它可以为 NULL。只是证明其安全性所需的分析对于 PREfast 而言过于复杂。

您可以使用 Microsoft 特定的扩展 __assume告诉编译器它不应产生此警告,但更好的解决方案是保留警告。每次使用/analyze 编译时(不必每次都编译),您应该验证它确实出现的警告仍然是误报。

如果你正确地使用你的断言(在编程过程中捕获逻辑错误,防止不能发生的情况,那么我认为你的代码没有问题,或者留下警告。添加代码来处理可能永远不会发生的问题是毫无意义的。您无缘无故地添加了更多代码和更多复杂性(如果它永远不会发生,那么您将无法从中恢复,因为您绝对不知道程序将处于什么状态。您所知道的是它已经进入了您认为不可能的代码路径。

但是,如果您将断言用作实际的错误处理(在特殊情况下值可以为 NULL,您只是希望它不会发生),那么它就是您代码中的一个缺陷.然后需要适当的错误处理(通常是异常)。

永远不要对可能的问题使用断言。使用它们来验证不可能没有发生。当/analyze 给你警告时,看看它们。如果它是误报,请忽略它(不要压制它,因为虽然它今天是误报,但您明天 checkin 的代码可能会把它变成一个真正的问题)。

关于c++ - 如何正确重写 ASSERT 代码以在 msvc 中传递/分析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2605674/

相关文章:

apache-flex - 是否有任何好的 actionscript/flex 程序可以计算代码行数、函数数、文件、包等

python - 查找 Python/Django 项目的所有未满足的依赖项

c++ - 关闭 fstream 是否保证文件系统同步?

c++ - 如何使用 FFmpeg 和 C/C++ 将数据流添加到 MXF(使用 mpeg2video)文件中

c++ - 为什么一个类方法在其对象文件中不存在而其他方法存在?

c++ - 如何将字符串的元素用作数字

code-analysis - 有没有人为FxCop/StyleCop创建任何很酷的规则?

c# - VC++ 中 "object of C# "的等价物是什么?

c++ - 如何提示 Visual C++ 编译器优化器不太可能执行 if 语句的特定分支?

c++ - 类、构造函数和指针类成员