構造体とクラスに注釈を付ける

インバリアントとして機能する注釈を使用して、構造体とクラスのメンバーに注釈を付けることができます。これらは、外側の構造体をパラメーターまたは結果値として含む関数の呼び出しまたは関数の開始/終了時に true と見なされます。

構造体とクラスの注釈

  • _Field_range_(low, high)

    フィールドは low から high までの範囲にあります (含む)。 適切な事前条件または事後条件を使用して、注釈付きオブジェクトに適用される _Satisfies_(_Curr_ >= low && _Curr_ <= high) と同じです。

  • _Field_size_(size), _Field_size_opt_(size), _Field_size_bytes_(size), _Field_size_bytes_opt_(size)

    size で指定されたように、要素 (またはバイト) 内の書き込み可能サイズを持つフィールド。

  • _Field_size_part_(size, count), _Field_size_part_opt_(size, count), _Field_size_bytes_part_(size, count), _Field_size_bytes_part_opt_(size, count)

    size によって指定された要素 (またはバイト) 内の書き込み可能サイズを持つフィールド、および読み取り可能な要素 (バイト) の count

  • _Field_size_full_(size), _Field_size_full_opt_(size), _Field_size_bytes_full_(size), _Field_size_bytes_full_opt_(size)

    size で指定されたように、要素 (またはバイト) 内の書き込みと書き込み可能サイズを持つフィールド。

  • _Field_z_

    Null で終わる文字列を含むフィールド。

  • _Struct_size_bytes_(size)

    構造体またはクラスの宣言に適用されます。 この型の有効なオブジェクトが、size で指定されているバイト数を使用して、宣言された型よりも大きくなる可能性があることを示します。 次に例を示します。

    
    typedef _Struct_size_bytes_(nSize)
    struct MyStruct {
        size_t nSize;
        ...
    };
    
    

    次に、MyStruct * 型のパラメーター pM のバッファー サイズをバイト単位で指定します。

    min(pM->nSize, sizeof(MyStruct))
    

#include <sal.h>

// This _Struct_size_bytes_ is equivalent to what below _Field_size_ means.
_Struct_size_bytes_(__builtin_offsetof(MyBuffer, buffer) + bufferSize * sizeof(int))
struct MyBuffer
{
    static int MaxBufferSize;

    _Field_z_
    const char* name;

    int firstField;

    // ... other fields

    _Field_range_(1, MaxBufferSize)
    int bufferSize;

    _Field_size_(bufferSize)        // Preferred way - easier to read and maintain.
    int buffer[]; // Using C99 Flexible array member
};

この例のメモ:

  • _Field_z__Null_terminated_ と等価です。 _Field_z_ [名前] フィールドには、[名前] フィールドが null で終わる文字列であることを指定します。
  • bufferSize_Field_range_bufferSize の値が 1 と MaxBufferSize (両方を含む) の範囲であることを指定します。
  • _Struct_size_bytes__Field_size_ の注釈の最終結果は同等です。 同様のレイアウトを持つ構造体またはクラスの場合、_Field_size_ は、同等の _Struct_size_bytes_ 注釈よりも参照と計算が少なくなるため、読み取りと保守が簡単になります。 _Field_size_ では、バイト サイズへの変換は必要ありません。 たとえば、void ポインター フィールドの場合など、バイト サイズが唯一のオプションである場合は、_Field_size_bytes_ を使用できます。 _Struct_size_bytes__Field_size_ の両方が存在する場合、両方がツールで利用できるようになります。 2 つの注釈が一致しない場合の対処方法は、ツールによって異なります。

関連項目