我希望这个问题不超出SO的范围; 如果是(对不起那种情况),请告诉我它属于哪里,我会尝试将它移到那里.
用于C/C++中静态代码分析的SAL注释的概念对我来说似乎非常有用.以MSDNwmemcpy上错误实现的示例为例:了解SAL:
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;
}
Run Code Online (Sandbox Code Playgroud)
MSDN说"代码分析工具可以通过单独分析这个功能来捕获错误",这看起来很棒,但问题是,当我在VS 2017社区中粘贴此代码时,没有关于此代码分析的警告,甚至没有启用所有分析警告.(像其他警告C26481 Don't use pointer arithmetic. Use span instead (bounds.1)..)
这应该产生警告(至少根据另一个例子回答什么是SAL(来源标注语言)的目的是什么SAL 1和2之间的差异),但不会:
_Success_(return) bool GetASmallInt(_Out_range_(0, 10) int& an_int);
//main:
int result;
const auto ret = GetASmallInt(result);
std::cout << …Run Code Online (Sandbox Code Playgroud) 如标题中所述:
SAL(源注释语言)的目的是什么?SAL 1和SAL 2之间有什么区别?
我理解使用的基础知识,这有助于突出传递给函数的每个变量的目的以及静态代码分析的各种其他内容,但它实际上有多大差异(忽略了参数要求的增加清晰度)该项目的其他程序员)?
如果我有以下原型:
_Success_(return == 1)
int TestFunction( _In_ int* pTest, _Inopt_ char* pOptional );
Run Code Online (Sandbox Code Playgroud)
这应该"告诉"静态分析器该函数在成功操作时将返回1,这pTest是一个必须不是指针,nullptr而且pOptional指针可能是也可能不是nullptr.但是,静态分析器不能从函数定义本身获取此信息吗?此外,它如何处理获得的信息,例如成功标准?
此外,为什么会出现SAL 1和SAL 2,为什么微软决定改变他们命名了他们的宏的方式之间的差异(即从__out到_Out_和__success到_Success_?)
我很抱歉,如果在MSDN上详细描述了这一点,但我无法在StackOverflow上找到它或任何其他问题并提供详细的答案,所以我想我会问我希望能满足我的好奇心.
在此先感谢您的时间!
在以下代码段中,根据 SAL 规范,在 MyFormat() 调用中错误使用格式说明符应该会产生警告,如果我取消对 printf() 相同调用的注释,我真的会收到所有这些警告,但我的代码是即使使用 /W4 也可以静默编译。我究竟做错了什么?我正在使用 MSVC 2017 15.9.7 社区版。
#include <stdio.h>
#include <stdarg.h>
void MyFormat(_Printf_format_string_ const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
va_end(va);
}
int main()
{
MyFormat("blabla %s\n", L"qq");
// printf("blabla %s\n", L"qq");
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我似乎从 Visual Studio 2019(16.5 预览版,但也在 16.4 及更早版本中)代码分析工具收到错误警告消息。这是一个错误,还是我真的只是错过了什么?
生成的警告(确切地说)是:
警告 C6385:从“prodlist”读取无效数据:可读大小为“(size_t)*32+8”字节,但可以读取“64”字节。
这是生成警告的代码(尽可能少)
#include <cstdint>
#include <string>
#include <iostream>
struct Product {
std::string price_profile;
};
int getNumRows() {
return 5;
}
Product *getProductsFromDB( int &numelements ) {
numelements = 0;
const int num_rows = getNumRows();
if ( num_rows == 0 ) {
numelements = 0;
return nullptr;
}
Product *prodlist = new Product[num_rows];
for ( int i = 0; i < num_rows; ++i ) {
prodlist[i].price_profile = "test"; // Warning on this …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Doxygen来记录一些使用 Microsoft源代码注释语言 (SAL)的 C++ 代码。但是,Doxygen 无法正确解析某些注释宏,例如_Success_、 。在示例函数注释的情况下,_Success_Doxygen 将此宏误解为函数头/原型。
以包含函数注释标记的以下示例为例:
/**
* @file
* Example with function annotation.
*/
#include <windows.h>
#include <sal.h>
/**
* @brief This is a function.
* @param i a random variable
* @return TRUE on every call.
*/
_Success_(return) // The SAL function annotation.
BOOL function(_In_ int i) {
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
对于上面的示例,Doxygen 将解释_Success_()为函数头/原型,从而创建绝对错误的文档。以下是带有和不带有函数注释的HTML Doxygen 输出:
通过 …
我正在尝试将Micosoft的SAL注释用于我的项目,但是我得到了以下警告,我不知道为什么.
作为一个例子,我创建了一个新的C++控制台应用程序,并拥有以下代码:
#include <sal.h>
class Whatever
{
public:
_Check_return_ int Method(__in int number) ;
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我使用Visual Studio 2008编译时,我收到以下警告:
警告C6540:在此函数上使用属性注释将使其所有现有的__declspec注释无效
在文件"c1xxast"中
我究竟做错了什么?如果我删除了_Check_return_或者__in,则警告消失.
我找不到任何关于警告C6550的参考.但是可以在这里找到相同的文本:http://msdn.microsoft.com/en-us/library/dd445322.aspx,但它不是很有帮助.
Deref和Outptr SAL 注释之间有什么区别?另外,什么时候使用不同类型的Outptr注释,例如 _Outptr_result_buffer_all_ 和 _Outptr_result_buffer_?
我试图找到替代LPWSTR将项目移植到gcc.
typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;
Run Code Online (Sandbox Code Playgroud)
什么是null终止?如果我这样做的话会安全吗
typedef WCHAR *LPWSTR
Run Code Online (Sandbox Code Playgroud) c++ ×8
sal ×8
annotations ×2
windows ×2
c ×1
char ×1
doxygen ×1
lpwstr ×1
visual-c++ ×1
winapi ×1