• VS中批注的使用


    SAL 是 Microsoft 源代码注释语言。 使用源代码批注,可以使代码背后的意图更加清晰。 这些注释还可以使用自动化的静态分析工具更准确地分析代码,显著减少误判。那么什么是批注,举个简单的例子,在函数参数或者返回值前边,有时候加 _in、 _out、 _inout之类的,这些就是批注。之前只是用的时候就会去查询各个批注的用法。用多了后干脆来一次大总结。下边是直接从msdn中转过来的,主要讲的是各个批注的用法和代表的含义。

    Header Annotations

    [This topic describes the annotations supported in the Windows headers through Windows 7. If you are developing for Windows 8, you should use the annotations described in SAL Annotations.]]

    Header annotations describe how a function uses its parameters and return value. These annotations have been added to many of the Windows header files to help you ensure that you are calling the Windows API correctly. If you enable code analysis, which is available starting with the Visual Studio 2005, the compiler will produce level 6000 warnings if you are not calling these functions per the usage described through the annotations. You can also add these annotations in your own code to ensure that it is being called correctly. To enable code analysis in Visual Studio, see the documentation for your version of Visual Studio.

    These annotations are defined in Specstrings.h. They are built on primitives that are part of the Standard Annotation Language (SAL) and implemented using _declspec("SAL_*").

    There are two classes of annotations: buffer annotations and advanced annotations.

    Buffer Annotations

    Buffer annotations describe how functions use their pointers and can be used to detect buffer overruns. Each parameter may use zero or one buffer annotation. A buffer annotation is constructed with a leading underscore and the components described in the following sections.

    Buffer sizeDescription

    (size)

    Specifies the total size of the buffer. Use with _bcount and _ecount; do not use with _part. This value is the accessible space; it may be less than the allocated space.

    (size,length)

    Specifies the total size and initialized length of the buffer. Use with _bcount_part and _ecount_part. The total size may be less than the allocated space.

    Buffer size unitsDescription

    _bcount

    The buffer size is in bytes.

    _ecount

    The buffer size is in elements.

    DirectionDescription

    _in

    The function reads from the buffer. The caller provides the buffer and initializes it.

    _inout

    The function both reads from and writes to buffer. The caller provides the buffer and initializes it. If used with _deref, the buffer may be reallocated by the function.

    _out

    The function writes to the buffer. If used on the return value or with _deref, the function provides the buffer and initializes it. Otherwise, the caller provides the buffer and the function initializes it.

    IndirectionDescription

    _deref

    Dereference the parameter to obtain the buffer pointer. This parameter may not be NULL.

    _deref_opt

    Dereference the parameter to obtain the buffer pointer. This parameter can be NULL.

    InitializationDescription

    _full

    The function initializes the entire buffer. Use only with output buffers.

    _part

    The function initializes part of the buffer, and explicitly indicates how much. Use only with output buffers.

    Required or optional bufferDescription

    _opt

    This parameter can be NULL.

    The following example shows the annotations for the GetModuleFileName function. The hModule parameter is an optional input parameter . ThelpFilename parameter is an output parameter; its size in characters is specified by the nSize parameter and its length includes the null-terminating character. The nSize parameter is an input parameter.

    DWORD
    WINAPI
    GetModuleFileName(
        __in_opt HMODULE hModule,
        __out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
        __in DWORD nSize
        );
    

      

    The following are the annotations defined in Specstrings.h. Use the information in the tables above to interpret their meaning.

    __bcount(size)
    __bcount_opt(size)
    __deref_bcount(size)
    __deref_bcount_opt(size)
    __deref_ecount(size)
    __deref_ecount_opt(size)
    __deref_in
    __deref_in_bcount(size)
    __deref_in_bcount_opt(size)
    __deref_in_ecount(size)
    __deref_in_ecount_opt(size)
    __deref_in_opt
    __deref_inout
    __deref_inout_bcount(size)
    __deref_inout_bcount_full(size)
    __deref_inout_bcount_full_opt(size)
    __deref_inout_bcount_opt(size)
    __deref_inout_bcount_part(size,length)
    __deref_inout_bcount_part_opt(size,length)
    __deref_inout_ecount(size)
    __deref_inout_ecount_full(size)
    __deref_inout_ecount_full_opt(size)
    __deref_inout_ecount_opt(size)
    __deref_inout_ecount_part(size,length)
    __deref_inout_ecount_part_opt(size,length)
    __deref_inout_opt
    __deref_opt_bcount(size)
    __deref_opt_bcount_opt(size)
    __deref_opt_ecount(size)
    __deref_opt_ecount_opt(size)
    __deref_opt_in
    __deref_opt_in_bcount(size)
    __deref_opt_in_bcount_opt(size)
    __deref_opt_in_ecount(size)
    __deref_opt_in_ecount_opt(size)
    __deref_opt_in_opt
    __deref_opt_inout
    __deref_opt_inout_bcount(size)
    __deref_opt_inout_bcount_full(size)
    __deref_opt_inout_bcount_full_opt(size)
    __deref_opt_inout_bcount_opt(size)
    __deref_opt_inout_bcount_part(size,length)
    __deref_opt_inout_bcount_part_opt(size,length)
    __deref_opt_inout_ecount(size)
    __deref_opt_inout_ecount_full(size)
    __deref_opt_inout_ecount_full_opt(size)
    __deref_opt_inout_ecount_opt(size)
    __deref_opt_inout_ecount_part(size,length)
    __deref_opt_inout_ecount_part_opt(size,length)
    __deref_opt_inout_opt
    __deref_opt_out
    __deref_opt_out_bcount(size)
    __deref_opt_out_bcount_full(size)
    __deref_opt_out_bcount_full_opt(size)
    __deref_opt_out_bcount_opt(size)
    __deref_opt_out_bcount_part(size,length)
    __deref_opt_out_bcount_part_opt(size,length)
    __deref_opt_out_ecount(size)
    __deref_opt_out_ecount_full(size)
    __deref_opt_out_ecount_full_opt(size)
    __deref_opt_out_ecount_opt(size)
    __deref_opt_out_ecount_part(size,length)
    __deref_opt_out_ecount_part_opt(size,length)
    __deref_opt_out_opt
    __deref_out
    __deref_out_bcount(size)
    __deref_out_bcount_full(size)
    __deref_out_bcount_full_opt(size)
    __deref_out_bcount_opt(size)
    __deref_out_bcount_part(size,length)
    __deref_out_bcount_part_opt(size,length)
    __deref_out_ecount(size)
    __deref_out_ecount_full(size)
    __deref_out_ecount_full_opt(size)
    __deref_out_ecount_opt(size)
    __deref_out_ecount_part(size,length)
    __deref_out_ecount_part_opt(size,length)
    __deref_out_opt
    __ecount(size)
    __ecount_opt(size)
    __in
    __in_bcount(size)
    __in_bcount_opt(size)
    __in_ecount(size)
    __in_ecount_opt(size)
    __in_opt
    __inout
    __inout_bcount(size)
    __inout_bcount_full(size)
    __inout_bcount_full_opt(size)
    __inout_bcount_opt(size)
    __inout_bcount_part(size,length)
    __inout_bcount_part_opt(size,length)
    __inout_ecount(size)
    __inout_ecount_full(size)
    __inout_ecount_full_opt(size)
    __inout_ecount_opt(size)
    __inout_ecount_part(size,length)
    __inout_ecount_part_opt(size,length)
    __inout_opt
    __out
    __out_bcount(size)
    __out_bcount_full(size)
    __out_bcount_full_opt(size)
    __out_bcount_opt(size)
    __out_bcount_part(size,length)
    __out_bcount_part_opt(size,length)
    __out_ecount(size)
    __out_ecount_full(size)
    __out_ecount_full_opt(size)
    __out_ecount_opt(size)
    __out_ecount_part(size,length)
    __out_ecount_part_opt(size,length)
    __out_opt

    Advanced Annotations

    Advanced annotations provide additional information about the parameter or return value. Each parameter or return value may use zero or one advanced annotation.

    AnnotationDescription

    __blocksOn(resource)

    The functions blocks on the specified resource.

    __callback

    The function can be used as a function pointer.

    __checkReturn

    Callers must check the return value.

    __format_string

    The parameter is a string that contains printf-style % markers.

    __in_awcount(expr,size)

    If the expression is true at exit, the size of the input buffer is specified in bytes. If the expression is false, the size is specified in elements.

    __nullnullterminated

    The buffer may be accessed up to and including the first sequence of two null characters or pointers.

    __nullterminated

    The buffer may be accessed up to and including the first null character or pointer.

    __out_awcount(expr,size)

    If the expression is true at exit, the size of the output buffer is specified in bytes. If the expression is false, the size is specified in elements.

    __override

    Specifies C#-style override behavior for virtual methods.

    __reserved

    The parameter is reserved for future use and must be zero or NULL.

    __success(expr)

    If the expression is true at exit, the caller can rely on all guarantees specified by other annotations. If the expression is false, the caller cannot rely on the guarantees. This annotation is automatically added to functions that return anHRESULT value.

    __typefix(ctype)

    Treat the parameter as the specified type rather than its declared type.

    The following examples show the buffer and advanced annotations for the DeleteTimerQueueTimerFreeEnvironmentStrings, andUnhandledExceptionFilter functions.

    C++

    __checkReturn
    BOOL
    WINAPI
    DeleteTimerQueueTimer(
        __in_opt HANDLE TimerQueue,
        __in     HANDLE Timer,
        __in_opt HANDLE CompletionEvent
        );
    
    BOOL
    WINAPI
    FreeEnvironmentStrings(
        __in __nullnullterminated LPTCH
        );
    
    __callback
    LONG
    WINAPI
    UnhandledExceptionFilter(
        __in struct _EXCEPTION_POINTERS *ExceptionInfo
        );
    

      

    在文档的本节中讨论文章 SAL 特性,为 SAL 语法参考,并给出其使用的示例。具体的使用方法点开链接直接看。

  • 相关阅读:
    重写
    mongodb版本区别
    mysql备份还原
    mysql备份恢复
    mysql的锁
    mysql索引
    mysql日志详解
    mysql基本语法
    mysql主从bin-log的三种方式
    mysql的GTID主从复制方式
  • 原文地址:https://www.cnblogs.com/guolixiucai/p/5019226.html
Copyright © 2020-2023  润新知