M i c r o s o f t Microsoft Microsoft 源代码注释语言 ( S A L SAL SAL ) 提供一组描述函数如何使用其参数的注释,有关注释的假设以及完成注释时的保证。 注释是在头文件 <sal.h> 中定义的。
#include <sal.h>同时它也叫:代码安全增强 与 标准注解 语言
2 简述作用M i c r o s o f t Microsoft Microsoft 教程原话是:
1) S A L SAL SAL 是让编译器为你检查代码的一种低成本的方法
2)使用 S A L SAL SAL 注释减少代码缺陷
其实就是提高 D e b u g Debug Debug 的效率!!!
其次,使用了 S A L SAL SAL 相当于给代码后面添加的注释一样,只不过面向不是其他人,而是编译器( M i c r o s o f t Microsoft Microsoft 教程原话是:编译器无法读取文档或非正式注释)
2-1 举个栗子memcpy 将源缓冲区中的 count 个字节复制到目标缓冲区:
不使用 S A L SAL SAL
void * memcpy(void *dest,const void *src,size_t count);此时编译器不知道传入的参数有什么作用。
使用 S A L SAL SAL
void * memcpy(_Out_writes_bytes_all_(count) void *dest,//参数是只读的,不进行修改_In_reads_bytes_(count) const void *src,//参数是只写的size_t count);不懂继续看下面的表
2-2 S A L SAL SAL 的检错能力 _Out_writes_bytes_all_(count)//count向编译器注明了参数的空间大小( c o u n t ) (count) (count) 注明了空间范围,这对编译器检查 空间溢出 空间溢出 空间溢出 这种 B u g Bug Bug 的效率无疑大大提高了。
空间溢出 空间溢出 空间溢出 的问题可能存在于 数组在遍历时读过头了 ,正式点叫:差一错误(BUG: O F F − B Y − O N E OFF-BY-ONE OFF−BY−ONE ERROR)
3 四种基本类型的参数 —— 对 形参 形参 形参 的注释 类别参数注释说明输入到调用的函数_In_数据传递给调用的函数,并被视为只读。输入到调用的函数并输出到调用方_Inout_可用数据传递到函数中,并可能进行修改。输出到调用方_Out_调用方只为调用的函数执行写入操作提供空间。 调用的函数将数据写入该空间。指针输出到调用方_Outptr_与“输出到调用方”一样。 调用的函数返回的值是一个指针。下表显示了如何区分必需参数和可选参数:
参数为必需参数参数为可选参数输入到调用的函数_In__In_opt_输入到调用的函数并输出到调用方_Inout__Inout_opt_输出到调用方_Out__Out_opt_指针输出到调用方_Outptr__Outptr_opt_这些注释帮助以正式且准确的方式识别可能的未初始化值和无效空指针的使用。 将 NULL 传递给必需参数可能会导致崩溃,或者可能会导致返回“失败”错误代码。 无论哪种情况,函数都无法成功完成其工作。
3-1 参数注释的区别 _In__In_opt_可否修改否否可否接受空指针否可_Out_ 与 _Out_opt_ ,_Inout_ 与 _Inout_opt_ ,_Outptr_ 与 _Outptr_opt_ 的关于空指针( N U L L NULL NULL)的接受性区别同理
3-2 Outptr面向 指针 指针 指针 的注释,以 _Outptr_ 不可接受空指针的范例展示其应用
void GoodOutPtrCallee(_Outptr_ int **pInt){int *pInt2 = new int;//为(局部)指针的指向对象分配内存空间*pInt2 = 5; //给(局部)指针的指向对象赋值*pInt = pInt2;//赋地址,pInt也指向pInt2的指向对象}void BadOutPtrCallee(_Outptr_ int **pInt){int *pInt2 = new int;// Did not initialize pInt buffer before returning!*pInt = pInt2;}void OutPtrCaller(void){int *pInt = NULL;//pInt:地址变量GoodOutPtrCallee(&pInt);//传入指针的地址BadOutPtrCallee(&pInt);} 4 对 形参 形参 形参 的注释可以对 函数 的 返回值 返回值 返回值 r e t v a l retval retval 进行注释
典型的栗子: r e t v a l retval retval 的类型是 b o o l bool bool 型的
_Success_ 注释与 _Out_ 组合:
_Success_(return != false) // Can also be stated as _Success_(return)bool GetValue(_Out_ int *pInt, bool flag){if(flag) {*pInt = 5;return true;} else {return false;}}当它为 t r u e true true 时,指示函数已成功
5 哪些情况添加 S A L SAL SAL 是必要 所有指针参数提供值范围注释(如数组,容器一类)