The most important annotations provide a consistent way to annotate buffer parameters or return values for a function. Each of these annotations describes a single buffer (which could be a string, a fixed-length or variable-length array, or just a pointer) that the function interacts with—where it is, how large it is, how much is initialized, and what the function does with it.
The appropriate macro for a given buffer can be constructed using the tables below. Pick an appropriate value from the Layers table, and then add any appropriate options from the Options table. Some combinations of values do not make sense as buffer annotations. Only meaningful annotations can be added to your code; for a list of these, see the buffer annotation definitions section in <sal.h>.
Only a single buffer annotation should be used for each parameter.
Layers
|
Possible choices
|
|---|
Parameters Layer
|
(none)
_In_
_Out_
_Inout_
_Deref_out_
|
Return Value Layer
|
_Ret_
_Deref_ret_
|
Pre / Post Layer
(used only if no suitable option exists in the Parameters layer or Return Value layer)
|
_Pre_
_Post_
_Deref_pre_
_Deref_post_
|
Options
|
Possible choices
|
|---|
Optional
|
(none)
opt_
|
Null-termination
|
(none)
z_
|
Extent
|
(none)
cap_[c_|x_](size)
bytecap_[c_|x_](size)
count_[c_|x_](size)
bytecount_[c_|x_](size)
ptrdiff_cap_(ptr)
ptrdiff_count_(ptr)
|
The various categories and their respective choices are described below.
Parameters Layer
Describes how the function uses the buffer of a formal parameter.
(none)
|
The buffer is not accessed. The caller must provide the buffer. This should only be used for alloc and free functions.
|
_In_
|
The function will only read from the buffer. The caller must provide the buffer and initialize it.
|
_Out_
|
The function will only write to the buffer. The caller must provide the buffer, and the function will initialize it.
|
_Inout_
|
The function may freely read from and write to the buffer. The caller must provide the buffer and initialize it.
|
_Deref_out_
|
This option applies to output parameters that are dereferenced. Given a parameter p, *p is the buffer pointer. p must not be NULL.
The function will only write to the buffer. The function will provide the buffer and initialize it.
|
Return Value Layer
Describes how the function uses the buffer of a return value.
(none)
|
The buffer is not accessed. The function will provide the buffer, and it will be uninitialized at exit. This should only be used for alloc and free functions.
|
_Ret_
|
The function will provide the buffer and initialize it.
|
_Deref_ret_
|
This option applies to return values that are dereferenced. Given a return value p, *p is the buffer pointer. p must not be NULL.
The function will provide the buffer and initialize it.
|
Pre / Post Layer
Describes how the function uses the buffer. Only use the values in this layer if the values in the Parameters layer or Return Value layer do not apply.
_Pre_
|
Describes conditions that must be met before a function is called.
|
_Post_
|
Describes conditions that must apply after a function is called.
|
_Deref_pre_
|
Describes conditions for array elements of dereferenced pointer parameters that must be met before the call
|
_Deref_post_
|
Describes conditions that must apply after a function is called.
|
Optional Option
Describes if the buffer itself is optional. These annotations can be applied to values in the Parameters layer, Return Value layer, or Pre / Post layer.
(none)
|
The pointer to the buffer must not be NULL.
|
opt_
|
The pointer to the buffer might be NULL. It will be checked before being dereferenced.
|
Null-Termination Option
States if the presence of a '\0' marks the end of valid elements in the buffer. These annotations can be applied to values in the Parameters layer, Return Value layer, or Pre / Post layer.
(none)
|
The buffer may not be null-terminated and a '\0' does not indicate the end of the buffer.
|
z_
|
A '\0' indicates the end of the buffer.
|
Extent Option
These options apply to readable and writable buffers. These annotations can be applied to values in the Parameters layer, Return Value layer, or Pre / Post layer.
(none)
|
The parameter or return value is not a readable or writable buffer.
|
cap_[c_|x_](size)
bytecap_[c_|x_](size)
ptrdiff_cap_(ptr)
|
Describes the writable size of the buffer. This option is typically used with the _Out_ annotation.
If the size is given in elements, use cap_. If the size is given in bytes, use bytecap_. If the size is given by a limiting pointer, use ptrdiff_cap_.
If the buffer size is a non-constant parameter, you do not need to specify c_ or x_. For example, valid annotations include cap_(size) and bytecap_(size).
If the buffer size is a constant expression, specify the c_ option. For example, valid annotations include cap_c_(size) and bytecap_c_(size).
If the buffer size is neither a constant expression nor a parameter, specify the x_ option. For example, valid annotations include cap_x_(size) and bytecap_x_(size).
|
count_[c_|x_](size)
bytecount_[c_|x_](size)
ptrdiff_count_(ptr)
|
Describes the writable size of the buffer. This option is typically used with the _In_ annotation.
If the size is given in elements, use count_. If the size is given in bytes, use bytecount_. If the size is given by a limiting pointer, use ptrdiff_count_.
If the buffer size is a non-constant parameter, you do not need to specify c_ or x_. For example, valid annotations include count_(size) and bytecount_(size).
If the buffer size is a constant expression, specify the c_ option. For example, valid annotations include count_c_(size) and bytecount_c_(size).
If the buffer size is neither a constant expression nor a parameter, specify the x_ option. For example, valid annotations include count_x_(size) and bytecount_x_(size).
|