Annotating Structs and Classes
You can annotate struct and class members by using annotations that act like invariants—they are presumed to be true at any function call or function entry/exit that involves the enclosing structure as a parameter or a result value.
Struct and Class Annotations
_Field_range_(low, high)
The field is in the range (inclusive) from
low
tohigh
. Equivalent to_Satisfies_(_Curr_ >= low && _Curr_ <= high)
applied to the annotated object by using the appropriate pre or post conditions._Field_size_(size)
,_Field_size_opt_(size)
,_Field_size_bytes_(size)
,_Field_size_bytes_opt_(size)
A field that has a writable size in elements (or bytes) as specified by
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)
A field that has a writable size in elements (or bytes) as specified by
size
, and thecount
of those elements (bytes) that are readable._Field_size_full_(size)
,_Field_size_full_opt_(size)
,_Field_size_bytes_full_(size)
,_Field_size_bytes_full_opt_(size)
A field that has both readable and writable size in elements (or bytes) as specified by
size
._Field_z_
A field that has a null-terminated string.
_Struct_size_bytes_(size)
Applies to struct or class declaration. Indicates that a valid object of that type may be larger than the declared type, with the number of bytes being specified by
size
. For example:typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
The buffer size in bytes of a parameter
pM
of typeMyStruct *
is then taken to be:min(pM->nSize, sizeof(MyStruct))
Example
#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
};
Notes for this example:
_Field_z_
is equivalent to_Null_terminated_
._Field_z_
for the name field specifies that the name field is a null-terminated string._Field_range_
forbufferSize
specifies that the value ofbufferSize
should be within 1 andMaxBufferSize
(both inclusive).- The end results of the
_Struct_size_bytes_
and_Field_size_
annotations are equivalent. For structures or classes that have a similar layout,_Field_size_
is easier to read and maintain, because it has fewer references and calculations than the equivalent_Struct_size_bytes_
annotation._Field_size_
doesn't require conversion to the byte size. If byte size is the only option, for example, for a void pointer field,_Field_size_bytes_
can be used. If both_Struct_size_bytes_
and_Field_size_
exist, both will be available to tools. It is up to the tool what to do if the two annotations disagree.