我希望这个问题不会超出SO的范围;如果是(在这种情况下很抱歉),请告诉我它的位置,我将尝试将其移到那里。
在C / C ++中用于静态代码分析的SAL annotations的概念对我来说真的很有用。以MSDN: Understanding SAL上错误实现的wmemcpy
示例为例:
wchar_t * wmemcpy(
_Out_writes_all_(count) wchar_t *dest,
_In_reads_(count) const wchar_t *src,
size_t count)
{
size_t i;
for (i = 0; i <= count; i++) { // BUG: off-by-one error
dest[i] = src[i];
}
return dest;
}
MSDN说,“一个代码分析工具可以通过单独分析此函数来捕获错误” ,这似乎很棒,但是问题是,当我将此代码粘贴到VS 2017 Community中时,没有关于这会在代码分析时弹出,甚至没有启用所有分析警告。 (其他警告,例如C26481 Don't use pointer arithmetic. Use span instead (bounds.1).
也会这样做。)
另一个示例,该示例应产生警告(至少根据an answer to What is the purpose of SAL (Source Annotation Language) and what is the difference between SAL 1 and 2?),但不会:
_Success_(return) bool GetASmallInt(_Out_range_(0, 10) int& an_int);
//main:
int result;
const auto ret = GetASmallInt(result);
std::cout << result;
还有一个错误警告的情况:
struct MyStruct { int *a; };
void RetrieveMyStruct(_Out_ MyStruct *result) {
result->a = new int(42);
}
//main:
MyStruct s;
RetrieveMyStruct(&s);
// C26486 Don't pass a pointer that may be invalid to a function. Parameter 1 's.a' in call to 'RetrieveMyStruct' may be invalid (lifetime.1).
// Don't pass a pointer that may be invalid to a function. The parameter in a call may be invalid (lifetime.1).
result
明显标有_Out_
而不是_In_
或_Inout_
,因此在这种情况下此警告没有意义。
我的问题是:为什么Visual Studio基于SAL的代码分析似乎很糟糕;为什么?我是否缺少某些东西?在这方面,Visual Studio Professional或Enterprise可能更好吗?还是有一个工具可以更好地做到这一点?
如果真的很糟糕:这是一个已知问题吗,也许有计划改进这种类型的分析吗?
相关:visual studio 2013 static code analysis - how reliable is it?
答案 0 :(得分:0)
Functions contracts(其中的SAL注释是一种轻量级的实现),使可以本地推理某个函数是在做正确的事情还是被错误使用或相反。没有它们,您只能在整个程序的上下文中讨论错误的概念。正如文档所述,有了它们,就可以在本地说出函数的行为是一个错误,并且您可以希望静态分析工具能够找到它。
即使有此帮助,也要机械地验证一段代码没有错误,这仍然是一个难题。由于存在多种解决问题的方法,因此存在不同的技术。它们都有优点和缺点,并且都包含许多启发式方法。循环是导致难以预测程序所有行为的部分原因,这些工具的实现者可能会选择不对极端简单的循环进行硬编码,因为这些模式在实践中很少使用。
如果真的很糟糕:这是一个已知问题吗,也许有计划改进这种类型的分析吗?
是的,研究人员已经在这个主题上研究了数十年,并继续改进理论和将理论思想转化为实用工具。作为用户,您可以选择: