Anotación de parámetros de función y valores devueltos
En este artículo se describen los usos típicos de anotaciones para parámetros de función simples (escalares y punteros a estructuras y clases) y la mayoría de los tipos de búferes. En este artículo también se muestran patrones de uso comunes de las anotaciones. Para información sobre otras anotaciones relacionadas con las funciones, consulte Anotación del comportamiento de la función.
Parámetros de puntero
Para las anotaciones de la tabla siguiente, cuando se anota un parámetro de puntero, el analizador notifica un error si el puntero es nulo. Esta anotación se aplica a punteros y a cualquier elemento de datos al que apunta.
Anotaciones y descripciones
_In_
Anota los parámetros de entrada que son escalares, estructuras, punteros a estructuras y similares. Se puede usar explícitamente en escalares simples. El parámetro debe ser válido en estado previo y no se modificará.
_Out_
Anota los parámetros de salida que son escalares, estructuras, punteros a estructuras y similares. No aplique esta anotación a un objeto que no pueda devolver un valor, por ejemplo, un escalar que se pasa por valor. El parámetro no tiene que ser válido en estado previo, pero debe ser válido en estado posterior.
_Inout_
Anota un parámetro que la función cambiará. Debe ser válido tanto en estado previo como posterior, pero se supone que tiene valores diferentes antes y después de la llamada. Debe aplicarse a un valor modificable.
_In_z_
Puntero a una cadena terminada en NULL que se usa como entrada. La cadena debe ser válida en estado previo. Se prefieren las variantes de
PSTR
, que ya tienen las anotaciones correctas._Inout_z_
Puntero a una matriz de caracteres terminados en NULL que se modificará. Debe ser válido antes y después de la llamada, pero se supone que el valor ha cambiado. El terminador nulo se puede mover, pero solo se puede tener acceso a los elementos hasta el terminador nulo original.
_In_reads_(s)
_In_reads_bytes_(s)
Puntero a una matriz, que la función lee. La matriz tiene un tamaño de
s
elementos, todos los cuales deben ser válidos.La variante
_bytes_
proporciona el tamaño en bytes en lugar de en elementos. Use esta variante solo cuando el tamaño no se pueda expresar como elementos. Por ejemplo, las cadenaschar
usarían la variante_bytes_
solo si una función similar que usawchar_t
también lo hiciera._In_reads_z_(s)
Puntero a una matriz terminada en NULL y que tiene un tamaño conocido. Los elementos hasta el terminador nulo (o
s
si no hay un terminador nulo) deben ser válidos en estado previo. Si el tamaño se conoce en bytes, escales
por el tamaño del elemento._In_reads_or_z_(s)
Puntero a una matriz terminada en NULL o que tiene un tamaño conocido, o ambos. Los elementos hasta el terminador nulo (o
s
si no hay un terminador nulo) deben ser válidos en estado previo. Si el tamaño se conoce en bytes, escales
por el tamaño del elemento. (Se usa para la familiastrn
)._Out_writes_(s)
_Out_writes_bytes_(s)
Puntero a una matriz de
s
elementos (bytes resp. ) que la función escribirá. Los elementos de matriz no tienen que ser válidos en estado previo y no se especifica el número de elementos que son válidos en estado posterior. Si hay anotaciones sobre el tipo de parámetro, se aplican en estado posterior. Por ejemplo, considere el fragmento de código siguiente:typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
En este ejemplo, el autor de la llamada proporciona un búfer de
size
elementos parap1
.MyStringCopy
hace que algunos de esos elementos sean válidos. Lo más importante es que la anotación_Null_terminated_
enPWSTR
significa quep1
termina en NULL en estado posterior. De este modo, el número de elementos válidos sigue estando bien definido, pero no se requiere un recuento de elementos específico.La variante
_bytes_
proporciona el tamaño en bytes en lugar de en elementos. Use esta variante solo cuando el tamaño no se pueda expresar como elementos. Por ejemplo, las cadenaschar
usarían la variante_bytes_
solo si una función similar que usawchar_t
también lo hiciera._Out_writes_z_(s)
Puntero a una matriz de
s
elementos. Los elementos no tienen que ser válidos en estado previo. En estado posterior, los elementos hasta el terminador nulo (que deben estar presentes) deben ser válidos. Si el tamaño se conoce en bytes, escales
por el tamaño del elemento._Inout_updates_(s)
_Inout_updates_bytes_(s)
Puntero a una matriz, que se lee y escribe en la función. Tiene un tamaño de
s
elementos y es válido en estado previo y posterior.La variante
_bytes_
proporciona el tamaño en bytes en lugar de en elementos. Use esta variante solo cuando el tamaño no se pueda expresar como elementos. Por ejemplo, las cadenaschar
usarían la variante_bytes_
solo si una función similar que usawchar_t
también lo hiciera._Inout_updates_z_(s)
Puntero a una matriz terminada en NULL y que tiene un tamaño conocido. Los elementos hasta el terminador nulo (que debe estar presente) deben ser válidos en estado previo y posterior. Se supone que el valor del estado posterior es diferente del valor en el estado previo, que incluye la ubicación del terminador nulo. Si el tamaño se conoce en bytes, escale
s
por el tamaño del elemento._Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
Puntero a una matriz de
s
elementos. Los elementos no tienen que ser válidos en estado previo. En estado posterior, los elementos hasta el enésimo elementoc
deben ser válidos. La variante_bytes_
se puede usar si el tamaño se conoce en bytes en lugar de en número de elementos.Por ejemplo:
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)
Puntero a una matriz, que la función lee y escribe. Tiene un tamaño de
s
elementos, todos los cuales deben ser válidos en estado previo, yc
elementos deben ser válidos en estado posterior.La variante
_bytes_
proporciona el tamaño en bytes en lugar de en elementos. Use esta variante solo cuando el tamaño no se pueda expresar como elementos. Por ejemplo, las cadenaschar
usarían la variante_bytes_
solo si una función similar que usawchar_t
también lo hiciera._Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
Puntero a una matriz, que la función de
s
elementos de tamaño lee y escribe. Se define como equivalente a:_Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))
En otras palabras, todos los elementos que existen en el búfer hasta
s
en el estado previo son válidos en el estado previo y posterior.La variante
_bytes_
proporciona el tamaño en bytes en lugar de en elementos. Use esta variante solo cuando el tamaño no se pueda expresar como elementos. Por ejemplo, las cadenaschar
usarían la variante_bytes_
solo si una función similar que usawchar_t
también lo hiciera._In_reads_to_ptr_(p)
Puntero a una matriz para la que
p - _Curr_
(es decir,p
menos_Curr_
) es una expresión válida. Los elementos delante dep
deben ser válidos en estado previo.Por ejemplo:
int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
_In_reads_to_ptr_z_(p)
Puntero a una matriz terminada en NULL para la que la expresión
p - _Curr_
(es decir,p
menos_Curr_
) es una expresión válida. Los elementos delante dep
deben ser válidos en estado previo._Out_writes_to_ptr_(p)
Puntero a una matriz para la que
p - _Curr_
(es decir,p
menos_Curr_
) es una expresión válida. Los elementos delante dep
no tienen que ser válidos en estado previo y deben ser válidos en estado posterior._Out_writes_to_ptr_z_(p)
Puntero a una matriz terminada en NULL para la que
p - _Curr_
(es decir,p
menos_Curr_
) es una expresión válida. Los elementos delante dep
no tienen que ser válidos en estado previo y deben ser válidos en estado posterior.
Parámetros de puntero opcionales
Cuando una anotación de parámetro de puntero incluye _opt_
, indica que el parámetro puede ser NULL. De lo contrario, la anotación se comporta igual que la versión que no incluye _opt_
. Esta es una lista de las variantes _opt_
de las anotaciones del parámetro de puntero:
_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_
Parámetros de puntero de salida
Los parámetros de puntero de salida requieren notación especial para eliminar la ambigüedad en la tenencia de valores NULL en el parámetro y la ubicación a la que apunta.
Anotaciones y descripciones
_Outptr_
El parámetro no puede ser nulo y, en el estado posterior, la ubicación a la que apunta no puede ser NULL y debe ser válida.
_Outptr_opt_
El parámetro puede ser nulo, pero en el estado posterior, la ubicación a la que apunta no puede ser NULL y debe ser válida.
_Outptr_result_maybenull_
El parámetro no puede ser nulo y, en el estado posterior, la ubicación a la que apunta puede ser NULL.
_Outptr_opt_result_maybenull_
El parámetro puede ser nulo y, en el estado posterior, la ubicación a la que apunta puede ser NULL.
En la tabla siguiente, se insertan subcadenas adicionales en el nombre de la anotación para calificar aún más el significado de la anotación. Las distintas subcadenas son
_z
,_COM_
,_buffer_
,_bytebuffer_
y_to_
.
Importante
Si la interfaz que está anotando es COM, use el formato COM de estas anotaciones. No use las anotaciones COM con ninguna otra interfaz de tipo.
_Outptr_result_z_
_Outptr_opt_result_z_
_Outptr_result_maybenull_z_
_Outptr_opt_result_maybenull_z_
El puntero devuelto tiene la anotación
_Null_terminated_
._COM_Outptr_
_COM_Outptr_opt_
_COM_Outptr_result_maybenull_
_COM_Outptr_opt_result_maybenull_
El puntero devuelto tiene semántica COM, por lo que lleva una condición posterior
_On_failure_
de que el puntero devuelto es NULL._Outptr_result_buffer_(s)
_Outptr_result_bytebuffer_(s)
_Outptr_opt_result_buffer_(s)
_Outptr_opt_result_bytebuffer_(s)
El puntero devuelto apunta a un búfer válido de
s
elementos o bytes de tamaño._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)
El puntero devuelto apunta a un búfer de
s
elementos o bytes de tamaño, del que el primerc
es válido.
Algunas convenciones de interfaz presuponen que los parámetros de salida se tratan como nulos en caso de error. Excepto el código explícitamente COM, se prefieren los formatos de la tabla siguiente. Para el código COM, use los formatos COM correspondientes que se enumeran en la sección anterior.
_Result_nullonfailure_
Modifica otras anotaciones. El resultado se establece en NULL si se produce un error en la función.
_Result_zeroonfailure_
Modifica otras anotaciones. El resultado se establece en cero si se produce un error en la función.
_Outptr_result_nullonfailure_
El puntero devuelto apunta a un búfer válido si la función se ejecuta correctamente o NULL, en caso contrario. Esta anotación es para un parámetro no opcional.
_Outptr_opt_result_nullonfailure_
El puntero devuelto apunta a un búfer válido si la función se ejecuta correctamente o NULL, en caso contrario. Esta anotación es para un parámetro opcional.
_Outref_result_nullonfailure_
El puntero devuelto apunta a un búfer válido si la función se ejecuta correctamente o NULL, en caso contrario. Esta anotación es para un parámetro de referencia.
Parámetros de referencia de salida
Un uso común del parámetro de referencia es para los parámetros de salida. Para los parámetros de referencia de salida simples, como int&
, _Out_
proporciona la semántica correcta. Sin embargo, cuando el valor de salida es un puntero, como int *&
, las anotaciones de puntero equivalentes como _Outptr_ int **
no proporcionan la semántica correcta. Para expresar concisamente la semántica de los parámetros de referencia de salida para los tipos de puntero, use estas anotaciones compuestas:
Anotaciones y descripciones
_Outref_
El resultado debe ser válido en estado posterior y no puede ser NULL.
_Outref_result_maybenull_
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado posterior.
_Outref_result_buffer_(s)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta a un búfer válido de
s
elementos de tamaño._Outref_result_bytebuffer_(s)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta a un búfer válido de
s
bytes de tamaño._Outref_result_buffer_to_(s, c)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta al búfer de
s
elementos, del que el primerc
es válido._Outref_result_bytebuffer_to_(s, c)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta al búfer de
s
bytes del que el primerc
es válido._Outref_result_buffer_all_(s)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta a un búfer válido de
s
elementos de tamaño válidos._Outref_result_bytebuffer_all_(s)
El resultado debe ser válido en estado posterior y no puede ser NULL. Apunta a un búfer válido de
s
bytes de elementos válidos._Outref_result_buffer_maybenull_(s)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado posterior. Apunta a un búfer válido de
s
elementos de tamaño._Outref_result_bytebuffer_maybenull_(s)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado posterior. Apunta a un búfer válido de
s
bytes de tamaño._Outref_result_buffer_to_maybenull_(s, c)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado posterior. Apunta al búfer de
s
elementos, del que el primerc
es válido._Outref_result_bytebuffer_to_maybenull_(s,c)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado previo. Apunta al búfer de
s
bytes del que el primerc
es válido._Outref_result_buffer_all_maybenull_(s)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado previo. Apunta a un búfer válido de
s
elementos de tamaño válidos._Outref_result_bytebuffer_all_maybenull_(s)
El resultado debe ser válido en estado posterior, pero puede ser NULL en estado previo. Apunta a un búfer válido de
s
bytes de elementos válidos.
Valores devueltos
El valor devuelto de una función es similar a un parámetro _Out_
, pero se encuentra en un nivel diferente de desreferencia, y no es necesario tener en cuenta el concepto del puntero al resultado. Para las anotaciones siguientes, el valor devuelto es el objeto anotado: un escalar, un puntero a una estructura o un puntero a un búfer. Estas anotaciones tienen la misma semántica que la anotación _Out_
correspondiente.
_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_
Parámetros de cadena de formato
_Printf_format_string_
Indica que el parámetro es una cadena de formato para una expresiónprintf
.Ejemplo
int MyPrintF(_Printf_format_string_ const wchar_t* format, ...) { va_list args; va_start(args, format); int ret = vwprintf(format, args); va_end(args); return ret; }
_Scanf_format_string_
Indica que el parámetro es una cadena de formato para una expresiónscanf
.Ejemplo
int MyScanF(_Scanf_format_string_ const wchar_t* format, ...) { va_list args; va_start(args, format); int ret = vwscanf(format, args); va_end(args); return ret; }
_Scanf_s_format_string_
Indica que el parámetro es una cadena de formato para una expresiónscanf_s
.Ejemplo
int MyScanF_s(_Scanf_s_format_string_ const wchar_t* format, ...) { va_list args; va_start(args, format); int ret = vwscanf_s(format, args); va_end(args); return ret; }
Otras anotaciones comunes
Anotaciones y descripciones
_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)
El parámetro, el campo o el resultado están en el intervalo (inclusivo) de
low
ahi
. Equivalente a_Satisfies_(_Curr_ >= low && _Curr_ <= hi)
que se aplica al objeto anotado junto con las condiciones de estado previo o posterior adecuadas.Importante
Aunque los nombres contienen "in" y "out", la semántica de
_In_
y_Out_
no se aplica a estas anotaciones._Pre_equal_to_(expr)
_Post_equal_to_(expr)
El valor anotado es exactamente
expr
. Equivalente a_Satisfies_(_Curr_ == expr)
que se aplica al objeto anotado junto con las condiciones de estado previo o posterior adecuadas._Struct_size_bytes_(size)
Se aplica a una declaración de clase o estructura. Indica que un objeto válido de ese tipo puede ser mayor que el tipo declarado, con el número de bytes proporcionados por
size
. Por ejemplo:typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
A continuación, se toma el tamaño del búfer en bytes de un parámetro
pM
de tipoMyStruct *
para que sea:min(pM->nSize, sizeof(MyStruct))