• 【VS2022】Microsoft 源代码注释语言 SAL


    M i c r o s o f t Microsoft Microsoft 源代码注释语言 S A L SAL SAL

    /**
     * @file            
     * @author			jUicE_g2R(qq:3406291309)————彬(bin-必应)
     *						通信与信息专业大二在读	
     * 
     * @brief			Microsoft 源代码注释语言 SAL
     * 
     * @copyright		2023.10
     * @COPYRIGHT			 原创技术笔记:转载需获得博主本人同意,且需标明转载源
     *
     * @language        C/C++
     *
     * @IDE			   Base on Microsoft Visual Studio 2022
     */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    jUicE_g2R的个人主页

    快速传送到 Microsoft 官方教程

    1 定义

    M i c r o s o f t Microsoft Microsoft 源代码注释语言 ( S A L SAL SAL ) 提供一组描述函数如何使用其参数的注释,有关注释的假设以及完成注释时的保证。 注释是在头文件 中定义的。

    #include 
    
    • 1

    同时它也叫:代码安全增强 与 标准注解 语言

    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
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时编译器不知道传入的参数有什么作用。

    使用 S A L SAL SAL

    void * memcpy(
       _Out_writes_bytes_all_(count) void *dest,		//参数是只读的,不进行修改
       _In_reads_bytes_(count) const void *src,			//参数是只写的
       size_t count
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    不懂继续看下面的表

    2-2 S A L SAL SAL 的检错能力

    _Out_writes_bytes_all_(count)						//count向编译器注明了参数的空间大小
    
    • 1

    ( c o u n t ) (count) (count) 注明了空间范围,这对编译器检查 空间溢出 空间溢出 空间溢出 这种 B u g Bug Bug 的效率无疑大大提高了。

    空间溢出 空间溢出 空间溢出 的问题可能存在于 数组在遍历时读过头了 ,正式点叫:差一错误(BUG: O F F − B Y − O N E OFF-BY-ONE OFFBYONE 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当它为 t r u e true true 时,指示函数已成功

    5 哪些情况添加 S A L SAL SAL 是必要

    • 所有指针参数
    • 提供值范围注释(如数组,容器一类)
  • 相关阅读:
    Spring Boot 实现字段唯一校验
    【MySQL篇】 MySQL基础学习
    死锁详细解读
    CSS 滚动捕获 scroll-snap-type
    java基础 日期工具类
    计算机算法分析与设计(21)---回溯法(图着色问题)
    PYQT中线程使用Demo
    数字信号处理-4-三角函数合成与傅里叶级数
    java复习-eclipse开发工具使用
    Redis-数据过期策略
  • 原文地址:https://blog.csdn.net/qq_73928885/article/details/133917579