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/