Note
This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
This article describes typical uses of annotations for simple function parameters—scalars, and pointers to structures and classes—and most kinds of buffers. This article also shows common usage patterns for annotations. For additional annotations that are related to functions, see Annotating Function Behavior
Pointer Parameters
For the annotations in the following table, when a pointer parameter is being annotated, the analyzer reports an error if the pointer is null. This applies to pointers and to any data item that's pointed to.
Annotations and Descriptions
- _In_- Annotates input parameters that are scalars, structures, pointers to structures and the like. Explicitly may be used on simple scalars. The parameter must be valid in pre-state and will not be modified. 
- _Out_- Annotates output parameters that are scalars, structures, pointers to structures and the like. Do not apply this to an object that cannot return a value—for example, a scalar that's passed by value. The parameter does not have to be valid in pre-state but must be valid in post-state. 
- _Inout_- Annotates a parameter that will be changed by the function. It must be valid in both pre-state and post-state, but is assumed to have different values before and after the call. Must apply to a modifiable value. 
- _In_z_- A pointer to a null-terminated string that's used as input. The string must be valid in pre-state. Variants of - PSTR, which already have the correct annotations, are preferred.
- _Inout_z_- A pointer to a null-terminated character array that will be modified. It must be valid before and after the call, but the value is assumed to have changed. The null terminator may be moved, but only the elements up to the original null terminator may be accessed. 
- _In_reads_(s)- _In_reads_bytes_(s)- A pointer to an array, which is read by the function. The array is of size - selements, all of which must be valid.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _In_reads_z_(s)- A pointer to an array that is null-terminated and has a known size. The elements up to the null terminator—or - sif there is no null terminator—must be valid in pre-state. If the size is known in bytes, scale- sby the element size.
- _In_reads_or_z_(s)- A pointer to an array that is null-terminated or has a known size, or both. The elements up to the null terminator—or - sif there is no null terminator—must be valid in pre-state. If the size is known in bytes, scale- sby the element size. (Used for the- strnfamily.)
- _Out_writes_(s)- _Out_writes_bytes_(s)- A pointer to an array of - selements (resp. bytes) that will be written by the function. The array elements do not have to be valid in pre-state, and the number of elements that are valid in post-state is unspecified. If there are annotations on the parameter type, they are applied in post-state. For example, consider the following code.- typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_ (size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);- In this example, the caller provides a buffer of - sizeelements for- p1.- MyStringCopymakes some of those elements valid. More importantly, the- _Null_terminated_annotation on- PWSTRmeans that- p1is null-terminated in post-state. In this way, the number of valid elements is still well-defined, but a specific element count is not required.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _Out_writes_z_(s)- A pointer to an array of - selements. The elements do not have to be valid in pre-state. In post-state, the elements up through the null terminator—which must be present—must be valid. If the size is known in bytes, scale- sby the element size.
- _Inout_updates_(s)- _Inout_updates_bytes_(s)- A pointer to an array, which is both read and written to in the function. It is of size - selements, and valid in pre-state and post-state.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _Inout_updates_z_(s)- A pointer to an array that is null-terminated and has a known size. The elements up through the null terminator—which must be present—must be valid in both pre-state and post-state. The value in the post-state is presumed to be different from the value in the pre-state; this includes the location of the null terminator. If the size is known in bytes, scale - sby the element size.
- _Out_writes_to_(s,c)- _Out_writes_bytes_to_(s,c)- _Out_writes_all_(s)- _Out_writes_bytes_all_(s)- A pointer to an array of - selements. The elements do not have to be valid in pre-state. In post-state, the elements up to the- c-th element must be valid. If the size is known in bytes, scale- sand- cby the element size or use the- _bytes_variant, which is defined as:- _Out_writes_to_(_Old_(s), _Old_(s)) _Out_writes_bytes_to_(_Old_(s), _Old_(s))- In other words, every element that exists in the buffer up to - sin the pre-state is valid in the post-state. For example:- void *memcpy(_Out_writes_bytes_all_(s) char *p1, _In_reads_bytes_(s) char *p2, _In_ int s); void * wordcpy(_Out_writes_all_(s) DWORD *p1, _In_reads_(s) DWORD *p2, _In_ int s);
- _Inout_updates_to_(s,c)- _Inout_updates_bytes_to_(s,c)- A pointer to an array, which is both read and written by the function. It is of size - selements, all of which must be valid in pre-state, and- celements must be valid in post-state.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _Inout_updates_z_(s)- A pointer to an array that is null-terminated and has a known size. The elements up through the null terminator—which must be present—must be valid in both pre-state and post-state. The value in the post-state is presumed to be different from the value in the pre-state; this includes the location of the null terminator. If the size is known in bytes, scale - sby the element size.
- _Out_writes_to_(s,c)- _Out_writes_bytes_to_(s,c)- _Out_writes_all_(s)- _Out_writes_bytes_all_(s)- A pointer to an array of - selements. The elements do not have to be valid in pre-state. In post-state, the elements up to the- c-th element must be valid. If the size is known in bytes, scale- sand- cby the element size or use the- _bytes_variant, which is defined as:- _Out_writes_to_(_Old_(s), _Old_(s)) _Out_writes_bytes_to_(_Old_(s), _Old_(s))- In other words, every element that exists in the buffer up to - sin the pre-state is valid in the post-state. For example:- void *memcpy(_Out_writes_bytes_all_(s) char *p1, _In_reads_bytes_(s) char *p2, _In_ int s); void * wordcpy(_Out_writes_all_(s) DWORD *p1, _In_reads_(s) DWORD *p2, _In_ int s);
- _Inout_updates_to_(s,c)- _Inout_updates_bytes_to_(s,c)- A pointer to an array, which is both read and written by the function. It is of size - selements, all of which must be valid in pre-state, and- celements must be valid in post-state.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _Inout_updates_all_(s)- _Inout_updates_bytes_all_(s)- A pointer to an array, which is both read and written by the function of size - selements. Defined as equivalent to:- _Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))- In other words, every element that exists in the buffer up to - sin the pre-state is valid in the pre-state and post-state.- The - _bytes_variant gives the size in bytes instead of elements. Use this only when the size cannot be expressed as elements. For example,- charstrings would use the- _bytes_variant only if a similar function that uses- wchar_twould.
- _In_reads_to_ptr_(p)- A pointer to an array for which the expression - p–- _Curr_(that is,- pminus- _Curr_) is defined by the appropriate language standard. The elements prior to- pmust be valid in pre-state.
- _In_reads_to_ptr_z_(p)- A pointer to a null-terminated array for which the expression - p–- _Curr_(that is,- pminus- _Curr_) is defined by the appropriate language standard. The elements prior to- pmust be valid in pre-state.
- _Out_writes_to_ptr_(p)- A pointer to an array for which the expression - p–- _Curr_(that is,- pminus- _Curr_) is defined by the appropriate language standard. The elements prior to- pdo not have to be valid in pre-state and must be valid in post-state.
- _Out_writes_to_ptr_z_(p)- A pointer to a null-terminated array for which the expression - p–- _Curr_(that is,- pminus- _Curr_) is defined by the appropriate language standard. The elements prior to- pdo not have to be valid in pre-state and must be valid in post-state.
Optional Pointer Parameters
When a pointer parameter annotation includes _opt_, it indicates that the parameter may be null. Otherwise, the annotation performs the same as the version that doesn't include _opt_. Here is a list of the _opt_ variants of the pointer parameter annotations:
_In_opt_, _Out_opt_, _Inout_opt_, _In_opt_z_, _Inout_opt_z_, _In_reads_opt_, _In_reads_bytes_opt_, _In_reads_opt_z_|_Out_writes_opt_, _Out_writes_opt_z_, _Inout_updates_opt_, _Inout_updates_bytes_opt_, _Inout_updates_opt_z_, _Out_writes_to_opt_, _Out_writes_bytes_to_opt_, _Out_writes_all_opt_, _Out_writes_bytes_all_opt_|_Inout_updates_to_opt_, _Inout_updates_bytes_to_opt_, _Inout_updates_all_opt_, _Inout_updates_bytes_all_opt_, _In_reads_to_ptr_opt_, _In_reads_to_ptr_opt_z_, _Out_writes_to_ptr_opt_, _Out_writes_to_ptr_opt_z_|
Output Pointer Parameters
Output pointer parameters require special notation to disambiguate null-ness on the parameter and the pointed-to location.
Annotations and Descriptions
- _Outptr_- Parameter cannot be null, and in the post-state the pointed-to location cannot be null and must be valid. 
- _Outptr_opt_- Parameter may be null, but in the post-state the pointed-to location cannot be null and must be valid. 
- _Outptr_result_maybenull_- Parameter cannot be null, and in the post-state the pointed-to location can be null. 
- _Outptr_opt_result_maybenull_- Parameter may be null, and in the post-state the pointed-to location can be null. - In the following table, additional substrings are inserted into the annotation name to further qualify the meaning of the annotation. The various substrings are - _z,- _COM_,- _buffer_,- _bytebuffer_, and- _to_.
Important
If the interface that you are annotating is COM, use the COM form of these annotations. Do not use the COM annotations with any other type interface.
Annotations and Descriptions
- _Outptr_result_z_- _Outptr_opt_result_z_- _Outptr_result_maybenull_z_- _Ouptr_opt_result_maybenull_z_- The returned pointer has the - _Null_terminated_annotation.
- _COM_Outptr_- _COM_Outptr_opt_- _COM_Outptr_result_maybenull_- _COM_Outptr_opt_result_maybenull_- The returned pointer has COM semantics, and therefore carries an - _On_failure_post-condition that the returned pointer is null.
- _Outptr_result_buffer_(s)- _Outptr_result_bytebuffer_(s)- _Outptr_opt_result_buffer_(s)- _Outptr_opt_result_bytebuffer_(s)- The returned pointer points to a valid buffer of size - selements or bytes.
- _Outptr_result_buffer_to_(s, c)- _Outptr_result_bytebuffer_to_(s, c)- _Outptr_opt_result_buffer_to_(s,c)- _Outptr_opt_result_bytebuffer_to_(s,c)- The returned pointer points to a buffer of size - selements or bytes, of which the first- care valid.- Certain interface conventions presume that output parameters are nullified on failure. Except for explicitly COM code, the forms in the following table are preferred. For COM code, use the corresponding COM forms that are listed in the previous section. - Annotations and Descriptions 
- _Result_nullonfailure_- Modifies other annotations. The result is set to null if the function fails. 
- _Result_zeroonfailure_- Modifies other annotations. The result is set to zero if the function fails. 
- _Outptr_result_nullonfailure_- The returned pointer points to a valid buffer if the function succeeds, or null if the function fails. This annotation is for a non-optional parameter. 
- _Outptr_opt_result_nullonfailure_- The returned pointer points to a valid buffer if the function succeeds, or null if the function fails. This annotation is for an optional parameter. 
- _Outref_result_nullonfailure_- The returned pointer points to a valid buffer if the function succeeds, or null if the function fails. This annotation is for a reference parameter. 
Output Reference Parameters
A common use of the reference parameter is for output parameters.  For simple output reference parameters—for example, int&—_Out_ provides the correct semantics.  However, when the output value is a pointer—for example int *&—the equivalent pointer annotations like _Outptr_ int ** don’t provide the correct semantics.  To concisely express the semantics of output reference parameters for pointer types, use these composite annotations:
Annotations and Descriptions
- _Outref_- Result must be valid in post-state and cannot be null. 
- _Outref_result_maybenull_- Result must be valid in post-state, but may be null in post-state. 
- _Outref_result_buffer_(s)- Result must be valid in post-state and cannot be null. Points to valid buffer of size - selements.
- _Outref_result_bytebuffer_(s)- Result must be valid in post-state and cannot be null. Points to valid buffer of size - sbytes.
- _Outref_result_buffer_to_(s, c)- Result must be valid in post-state and cannot be null. Points to buffer of - selements, of which the first- care valid.
- _Outref_result_bytebuffer_to_(s, c)- Result must be valid in post-state and cannot be null. Points to buffer of - sbytes of which the first- care valid.
- _Outref_result_buffer_all_(s)- Result must be valid in post-state and cannot be null. Points to valid buffer of size - svalid elements.
- _Outref_result_bytebuffer_all_(s)- Result must be valid in post-state and cannot be null. Points to valid buffer of - sbytes of valid elements.
- _Outref_result_buffer_maybenull_(s)- Result must be valid in post-state, but may be null in post-state. Points to valid buffer of size - selements.
- _Outref_result_bytebuffer_maybenull_(s)- Result must be valid in post-state, but may be null in post-state. Points to valid buffer of size - sbytes.
- _Outref_result_buffer_to_maybenull_(s, c)- Result must be valid in post-state, but may be null in post-state. Points to buffer of - selements, of which the first- care valid.
- _Outref_result_bytebuffer_to_maybenull_(s,c)- Result must be valid in post-state, but may be null in post state. Points to buffer of - sbytes of which the first- care valid.
- _Outref_result_buffer_all_maybenull_(s)- Result must be valid in post-state, but may be null in post state. Points to valid buffer of size - svalid elements.
- _Outref_result_bytebuffer_all_maybenull_(s)- Result must be valid in post-state, but may be null in post state. Points to valid buffer of - sbytes of valid elements.
Return Values
The return value of a function resembles an _Out_ parameter but is at a different level of de-reference, and you don't have to consider the concept of the pointer to the result.  For the following annotations, the return value is the annotated object—a scalar, a pointer to a struct, or a pointer to a buffer. These annotations have the same semantics as the corresponding _Out_ annotation.
_Ret_z_, _Ret_writes_(s), _Ret_writes_bytes_(s), _Ret_writes_z_(s), _Ret_writes_to_(s,c), _Ret_writes_maybenull_(s), _Ret_writes_to_maybenull_(s), _Ret_writes_maybenull_z_(s)|_Ret_maybenull_, _Ret_maybenull_z_, _Ret_null_, _Ret_notnull_, _Ret_writes_bytes_to_, _Ret_writes_bytes_maybenull_, _Ret_writes_bytes_to_maybenull_
Other Common Annotations
Annotations and Descriptions
- _In_range_(low, hi)- _Out_range_(low, hi)- _Ret_range_(low, hi)- _Deref_in_range_(low, hi)- _Deref_out_range_(low, hi)- _Deref_inout_range_(low, hi)- _Field_range_(low, hi)- The parameter, field, or result is in the range (inclusive) from - lowto- hi. Equivalent to- _Satisfies_(_Curr_ >= low && _Curr_ <= hi)that is applied to the annotated object together with the appropriate pre-state or post-state conditions.- Important - Although the names contain "in" and "out", the semantics of - _In_and- _Out_do not apply to these annotations.
- _Pre_equal_to_(expr)- _Post_equal_to_(expr)- The annotated value is exactly - expr. Equivalent to- _Satisfies_(_Curr_ == expr)that is applied to the annotated object together with the appropriate pre-state or post-state conditions.
- _Struct_size_bytes_(size)- Applies to a 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 given by - size. For example:- typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };- The buffer size in bytes of a parameter - pMof type- MyStruct *is then taken to be:- min(pM->nSize, sizeof(MyStruct))
Related Resources
See Also
Using SAL Annotations to Reduce C/C++ Code Defects
Understanding SAL
Annotating Function Behavior
Annotating Structs and Classes
Annotating Locking Behavior
Specifying When and Where an Annotation Applies
Intrinsic Functions
Best Practices and Examples