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 caracteres char usariam a variante _bytes_ somente se essa variante também fosse usada por uma função semelhante que usa wchar_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, dimensione s 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, dimensione s pelo tamanho do elemento. (Usado para a família strn.)

  • _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 para p1. MyStringCopy torna alguns desses elementos válidos. Mais importante, a anotação _Null_terminated_ em PWSTR significa que p1 é 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 caracteres char usariam a variante _bytes_ somente se essa variante também fosse usada por uma função semelhante que usa wchar_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, dimensione s 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 caracteres char usariam a variante _bytes_ somente se essa variante também fosse usada por uma função semelhante que usa wchar_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é o cº 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 elementos c 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 caracteres char usariam a variante _bytes_ somente se essa variante também fosse usada por uma função semelhante que usa wchar_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 caracteres char usariam a variante _bytes_ somente se essa variante também fosse usada por uma função semelhante que usa wchar_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 de p 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 de p 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 de p 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 de p 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 primeiros c 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 primeiros c 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 primeiros c 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 primeiros c 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 primeiros c 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 de retorno

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ão printf.

    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ão scanf.

    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ão scanf_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 a hi (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 tipo MyStruct * é então usado para ser:

    min(pM->nSize, sizeof(MyStruct))

Confira também