Anotando parâmetros de função e valores retornados
Este artigo descreve os usos típicos de anotações para parâmetros de função simples, escalares e ponteiros para estruturas e classes, e a maioria dos tipos de buffers. Este artigo também mostra padrões de uso comuns para anotações. Para anotações adicionais relacionadas a funções, confira Anotando o comportamento da função.
Parâmetros de ponteiro
Para as anotações na tabela a seguir, quando um parâmetro de ponteiro é anotado, o analisador relata um erro se o ponteiro é nulo. Essa anotação se aplica a ponteiros e a qualquer item de dados que seja apontado.
Anotações e descrições
_In_
Anota parâmetros de entrada que são escalares, estruturas, ponteiros para estruturas e similares. Pode ser usado explicitamente em escalares simples. O parâmetro precisa ser válido no pré-estado e não será modificado.
_Out_
Anota parâmetros de saída que são escalares, estruturas, ponteiros para estruturas e similares. Não aplique essa anotação a um objeto que não possa retornar um valor, por exemplo, um escalar passado por valor. O parâmetro não precisa ser válido no pré-estado, mas precisa ser válido no pós-estado.
_Inout_
Anota um parâmetro que será alterado pela função. Ele precisa ser válido no pré-estado e no pós-estado, mas supõe-se que tenha valores diferentes antes e depois da chamada. Precisa ser aplicável a um valor modificável.
_In_z_
Um ponteiro para uma cadeia de caracteres terminada em nulo usada como entrada. A cadeia de caracteres precisa ser válida no pré-estado. Variantes de
PSTR
, que já têm as anotações corretas, são preferíveis._Inout_z_
Um ponteiro para uma matriz de caracteres terminada em nulo que será modificada. Ele precisa ser válido antes e depois da chamada, mas supõe-se que o valor foi alterado. O terminador nulo pode ser movido, mas somente os elementos até o terminador nulo original podem ser acessados.
_In_reads_(s)
_In_reads_bytes_(s)
Um ponteiro para uma matriz, que é lida pela função. A matriz é de elementos de tamanho
s
, todos os quais precisam ser válidos.A variante
_bytes_
fornece o tamanho em bytes em vez de elementos. Use essa variante somente quando o tamanho não puder ser expresso como elementos. Por exemplo, as cadeias de caractereschar
usariam a variante_bytes_
somente se essa variante também fosse usada por uma função semelhante que usawchar_t
._In_reads_z_(s)
Um ponteiro para uma matriz terminada em nulo e que tem um tamanho conhecido. Os elementos até o terminador nulo (ou
s
, se não houver um terminador nulo) precisam ser válidos no pré-estado. Se o tamanho for conhecido em bytes, dimensiones
pelo tamanho do elemento._In_reads_or_z_(s)
Um ponteiro para uma matriz terminada em nulo ou que tem um tamanho conhecido ou ambos. Os elementos até o terminador nulo (ou
s
, se não houver um terminador nulo) precisam ser válidos no pré-estado. Se o tamanho for conhecido em bytes, dimensiones
pelo tamanho do elemento. (Usado para a famíliastrn
.)_Out_writes_(s)
_Out_writes_bytes_(s)
Um ponteiro para uma matriz de elementos
s
(bytes de resp.) que será gravado pela função. Os elementos da matriz não precisam ser válidos no pré-estado e o número de elementos válidos no pós-estado não é especificado. Se houver anotações no tipo de parâmetro, elas serão aplicadas no pós-estado. Por exemplo, considere o código a seguir.typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
Neste exemplo, o chamador fornece um buffer de elementos
size
parap1
.MyStringCopy
torna alguns desses elementos válidos. Mais importante, a anotação_Null_terminated_
emPWSTR
significa quep1
é terminada em nulo no pós-estado. Dessa forma, o número de elementos válidos ainda é bem definido, mas uma contagem de elementos específica não é necessária.A variante
_bytes_
fornece o tamanho em bytes em vez de elementos. Use essa variante somente quando o tamanho não puder ser expresso como elementos. Por exemplo, as cadeias de caractereschar
usariam a variante_bytes_
somente se essa variante também fosse usada por uma função semelhante que usawchar_t
._Out_writes_z_(s)
Um ponteiro para uma matriz de elementos
s
. Os elementos não precisam ser válidos no pré-estado. No pós-estado, os elementos até o terminador nulo (que precisa estar presente) precisam ser válidos. Se o tamanho for conhecido em bytes, dimensiones
pelo tamanho do elemento._Inout_updates_(s)
_Inout_updates_bytes_(s)
Um ponteiro para uma matriz, que é lida e gravada na função. Ele é composto de elementos de tamanho
s
e válido em pré-estado e pós-estado.A variante
_bytes_
fornece o tamanho em bytes em vez de elementos. Use essa variante somente quando o tamanho não puder ser expresso como elementos. Por exemplo, as cadeias de caractereschar
usariam a variante_bytes_
somente se essa variante também fosse usada por uma função semelhante que usawchar_t
._Inout_updates_z_(s)
Um ponteiro para uma matriz terminada em nulo e que tem um tamanho conhecido. Os elementos até o terminador nulo (que precisa estar presente) precisam ser válidos tanto no pré-estado quanto no pós-estado. Presume-se que o valor no pós-estado seja diferente do valor no pré-estado; que inclui o local do terminador nulo. Se o tamanho for conhecido em bytes, dimensione
s
pelo tamanho do elemento._Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
Um ponteiro para uma matriz de elementos
s
. Os elementos não precisam ser válidos no pré-estado. No pós-estado, os elementos até oc
º elemento precisam ser válidos. A variante_bytes_
poderá ser usada se o tamanho for conhecido em bytes em vez de número de elementos.Por exemplo:
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)
Um ponteiro para uma matriz, que é lida e gravada pela função. Ele é composto de elementos de tamanho
s
, todos os quais precisam ser válidos em pré-estado, e os elementosc
precisam ser válidos no pós-estado.A variante
_bytes_
fornece o tamanho em bytes em vez de elementos. Use essa variante somente quando o tamanho não puder ser expresso como elementos. Por exemplo, as cadeias de caractereschar
usariam a variante_bytes_
somente se essa variante também fosse usada por uma função semelhante que usawchar_t
._Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
Um ponteiro para uma matriz, que é lida e gravada pela função de elementos de tamanho
s
. Definido como equivalente a:_Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))
Em outras palavras, cada elemento que existe no buffer até
s
no pré-estado é válido no pré-estado e no pós-estado.A variante
_bytes_
fornece o tamanho em bytes em vez de elementos. Use essa variante somente quando o tamanho não puder ser expresso como elementos. Por exemplo, as cadeias de caractereschar
usariam a variante_bytes_
somente se essa variante também fosse usada por uma função semelhante que usawchar_t
._In_reads_to_ptr_(p)
Um ponteiro para uma matriz para a qual
p - _Curr_
(ou seja,p
menos_Curr_
) é uma expressão válida. Os elementos antes dep
precisam ser válidos no pré-estado.Por exemplo:
int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
_In_reads_to_ptr_z_(p)
Um ponteiro para uma matriz terminada em nulo para a qual a expressão
p - _Curr_
(ou seja,p
menos_Curr_
) é uma expressão válida. Os elementos antes dep
precisam ser válidos no pré-estado._Out_writes_to_ptr_(p)
Um ponteiro para uma matriz para a qual
p - _Curr_
(ou seja,p
menos_Curr_
) é uma expressão válida. Os elementos antes dep
não precisam ser válidos no pré-estado e precisam ser válidos no pós-estado._Out_writes_to_ptr_z_(p)
Um ponteiro para uma matriz terminada em nulo para a qual a
p - _Curr_
(ou seja,p
menos_Curr_
) é uma expressão válida. Os elementos antes dep
não precisam ser válidos no pré-estado e precisam ser válidos no pós-estado.
Parâmetros de ponteiro opcionais
Quando uma anotação de parâmetro de ponteiro inclui _opt_
, isso indica que o parâmetro pode ser nulo. Caso contrário, a anotação se comporta da mesma forma que a versão que não inclui _opt_
. Aqui está uma lista das variantes _opt_
das anotações de parâmetro de ponteiro:
_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 ponteiro de saída
Os parâmetros de ponteiro de saída exigem notação especial para desambiguar a nulidade no parâmetro e no local apontado.
Anotações e descrições
_Outptr_
O parâmetro não pode ser nulo e, no pós-estado, o local apontado não pode ser nulo e precisa ser válido.
_Outptr_opt_
O parâmetro pode ser nulo mas, no pós-estado, o local apontado não pode ser nulo e precisa ser válido.
_Outptr_result_maybenull_
O parâmetro não pode ser nulo e, no pós-estado, o local apontado pode ser nulo.
_Outptr_opt_result_maybenull_
O parâmetro pode ser nulo e, no pós-estado, o local apontado pode ser nulo.
Na tabela a seguir, substrings adicionais são inseridas no nome da anotação para qualificar ainda mais o significado da anotação. As várias substrings são
_z
,_COM_
,_buffer_
,_bytebuffer_
e_to_
.
Importante
Se a interface que você está anotando for COM, use a forma COM dessas anotações. Não use as anotações COM com nenhuma outra interface de tipo.
_Outptr_result_z_
_Outptr_opt_result_z_
_Outptr_result_maybenull_z_
_Outptr_opt_result_maybenull_z_
O ponteiro retornado tem a anotação
_Null_terminated_
._COM_Outptr_
_COM_Outptr_opt_
_COM_Outptr_result_maybenull_
_COM_Outptr_opt_result_maybenull_
O ponteiro retornado tem semântica COM, razão pela qual ele carrega uma pós-condição
_On_failure_
em que o ponteiro retornado é nulo._Outptr_result_buffer_(s)
_Outptr_result_bytebuffer_(s)
_Outptr_opt_result_buffer_(s)
_Outptr_opt_result_bytebuffer_(s)
O ponteiro retornado aponta para um buffer válido de bytes ou elementos de tamanho
s
._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)
O ponteiro retornado aponta para um buffer de bytes ou elementos de tamanho
s
, dos quais os primeirosc
são válidos.
Determinadas convenções de interface presumem que os parâmetros de saída são anulados em caso de falha. Exceto pelo código COM explicitamente, os formulários na tabela a seguir são preferíveis. Para código COM, use os formulários COM correspondentes listados na seção anterior.
_Result_nullonfailure_
Modifica outras anotações. O resultado será definido como nulo se a função falhar.
_Result_zeroonfailure_
Modifica outras anotações. O resultado será definido como zero se a função falhar.
_Outptr_result_nullonfailure_
O ponteiro retornado apontará para um buffer válido se a função for bem-sucedida ou nulo se a função falhar. Essa anotação é para um parâmetro não opcional.
_Outptr_opt_result_nullonfailure_
O ponteiro retornado apontará para um buffer válido se a função for bem-sucedida ou nulo se a função falhar. Essa anotação é para um parâmetro opcional.
_Outref_result_nullonfailure_
O ponteiro retornado apontará para um buffer válido se a função for bem-sucedida ou nulo se a função falhar. Essa anotação é para um parâmetro de referência.
Parâmetros de referência de saída
Um uso comum do parâmetro de referência é para parâmetros de saída. Para parâmetros de referência de saída simples, como int&
, _Out_
fornece a semântica correta. No entanto, quando o valor de saída é um ponteiro (como int *&
), as anotações de ponteiro equivalentes (como _Outptr_ int **
) não fornecem a semântica correta. Para expressar concisamente a semântica dos parâmetros de referência de saída para tipos de ponteiro, use estas anotações compostas:
Anotações e descrições
_Outref_
O resultado precisa ser válido no pós-estado e não pode ser nulo.
_Outref_result_maybenull_
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado.
_Outref_result_buffer_(s)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para um buffer válido de elementos de tamanho
s
._Outref_result_bytebuffer_(s)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para um buffer válido de bytes de tamanho
s
._Outref_result_buffer_to_(s, c)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para o buffer de elementos
s
, dos quais os primeirosc
são válidos._Outref_result_bytebuffer_to_(s, c)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para o buffer de bytes
s
, dos quais os primeirosc
são válidos._Outref_result_buffer_all_(s)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para um buffer válido de elementos válidos de tamanho
s
._Outref_result_bytebuffer_all_(s)
O resultado precisa ser válido no pós-estado e não pode ser nulo. Aponta para um buffer válido de bytes
s
de elementos válidos._Outref_result_buffer_maybenull_(s)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para um buffer válido de elementos de tamanho
s
._Outref_result_bytebuffer_maybenull_(s)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para um buffer válido de bytes de tamanho
s
._Outref_result_buffer_to_maybenull_(s, c)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para o buffer de elementos
s
, dos quais os primeirosc
são válidos._Outref_result_bytebuffer_to_maybenull_(s,c)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para o buffer de bytes
s
, dos quais os primeirosc
são válidos._Outref_result_buffer_all_maybenull_(s)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para um buffer válido de elementos válidos de tamanho
s
._Outref_result_bytebuffer_all_maybenull_(s)
O resultado precisa ser válido no pós-estado, mas pode ser nulo no pós-estado. Aponta para um buffer válido de bytes
s
de elementos válidos.
Valores retornados
O valor retornado de uma função se assemelha a um parâmetro _Out_
, mas está em um nível diferente de referência e você não precisa considerar o conceito do ponteiro para o resultado. Para as anotações a seguir, o valor retornado é o objeto anotado: um escalar, um ponteiro para um struct ou um ponteiro para um buffer. Essas anotações têm a mesma semântica que a anotação _Out_
correspondente.
_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 cadeia de caracteres de formato
_Printf_format_string_
Indica que o parâmetro é uma cadeia de caracteres de formato para uso em uma expressãoprintf
.Exemplo
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 o parâmetro é uma cadeia de caracteres de formato para uso em uma expressãoscanf
.Exemplo
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 o parâmetro é uma cadeia de caracteres de formato para uso em uma expressãoscanf_s
.Exemplo
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; }
Outras anotações comuns
Anotações e descrições
_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)
O parâmetro, o campo ou o resultado está no intervalo de
low
ahi
(inclusive). Equivalente a_Satisfies_(_Curr_ >= low && _Curr_ <= hi)
, que é aplicado ao objeto anotado junto com as condições de pré-estado ou pós-estado apropriadas.Importante
Embora os nomes contenham "in" e "out", a semântica de
_In_
e_Out_
não se aplica a essas anotações._Pre_equal_to_(expr)
_Post_equal_to_(expr)
O valor anotado é exatamente
expr
. Equivalente a_Satisfies_(_Curr_ == expr)
, que é aplicado ao objeto anotado junto com as condições de pré-estado ou pós-estado apropriadas._Struct_size_bytes_(size)
Aplica-se a uma declaração de classe ou struct. Indica que um objeto válido desse tipo pode ser maior que o tipo declarado, com o número de bytes sendo fornecido por
size
. Por exemplo:typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
O tamanho do buffer em bytes de um parâmetro
pM
de tipoMyStruct *
é então usado para ser:min(pM->nSize, sizeof(MyStruct))