Поделиться через


Аннотирование параметров функции и возвращаемых значений

В этой статье описывается типичное использование заметок для простых параметров функции — скалярных и указателей на структуры и классы— и большинство типов буферов. В этой статье также показаны распространенные шаблоны использования примечаний. Дополнительные заметки, связанные с функциями, см. в разделе "Поведение функции аннотирования".

Параметры указателя

Для заметок в следующей таблице при аннотации параметра указателя анализатор сообщает об ошибке, если указатель имеет значение NULL. Эта заметка относится к указателям и к любому элементу данных, на который указывается.

Заметки и описания

  • _In_

    Определяет входные параметры, которые являются скалярными, структурами, указателями на структуры и подобные. Явно можно использовать для простых скаляр. Параметр должен быть допустимым в предварительном состоянии и не будет изменен.

  • _Out_

    Определяет выходные параметры, которые являются скалярными, структурами, указателями на структуры и подобные. Не применяйте эту заметку к объекту, который не может возвращать значение, например скаляр, передаваемый по значению. Параметр не должен быть допустимым в предварительном состоянии, но должен быть допустимым в пост-состоянии.

  • _Inout_

    Заметит параметр, который будет изменен функцией. Он должен быть допустимым как в предварительном, так и в пост-состоянии, но предполагается, что они имеют разные значения до и после вызова. Должен применяться к модификируемому значению.

  • _In_z_

    Указатель на строку, завершающую значение NULL, которая используется в качестве входных данных. Строка должна быть допустимой в предварительном состоянии. Варианты PSTR, которые уже имеют правильные заметки, предпочтительнее.

  • _Inout_z_

    Указатель на массив символов, завершающийся значением NULL, который будет изменен. Он должен быть допустимым до и после вызова, но предполагается, что значение изменилось. Конечный элемент NULL может быть перемещен, но к исходному терминатору null можно получить доступ только к элементам.

  • _In_reads_(s)

    _In_reads_bytes_(s)

    Указатель на массив, который считывается функцией. Массив содержит элементы размера s , все из которых должны быть допустимыми.

    Вариант _bytes_ предоставляет размер в байтах вместо элементов. Используйте этот вариант, только если размер не может быть выражен как элементы. Например, строки будут использовать _bytes_ вариант только в том случае, char если аналогичная функция, которая будет использоватьwchar_t.

  • _In_reads_z_(s)

    Указатель на массив, завершающийся значением NULL, и имеет известный размер. Элементы до конца null ( или s , если нет конца NULL), должны быть допустимыми в предварительном состоянии. Если размер известен в байтах, масштабируйте s по размеру элемента.

  • _In_reads_or_z_(s)

    Указатель на массив, который завершается значением NULL или имеет известный размер или оба. Элементы до конца null ( или s , если нет конца NULL), должны быть допустимыми в предварительном состоянии. Если размер известен в байтах, масштабируйте s по размеру элемента. (Используется для strn семьи.)

  • _Out_writes_(s)

    _Out_writes_bytes_(s)

    Указатель на массив s элементов (resp. bytes), который будет записан функцией. Элементы массива не должны быть допустимыми в предварительном состоянии, а количество элементов, допустимых в пост-состоянии, не указано. Если в типе параметра есть заметки, они применяются в пост-состоянии. Например, рассмотрим следующий код.

    typedef _Null_terminated_ wchar_t *PWSTR;
    void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
    

    В этом примере вызывающий объект предоставляет буфер size элементов для p1. MyStringCopy делает некоторые из этих элементов допустимыми. Более важно, что заметка _Null_terminated_ означает PWSTR , что p1 значение NULL завершается в пост-состоянии. Таким образом, число допустимых элементов по-прежнему четко определено, но определенное число элементов не требуется.

    Вариант _bytes_ предоставляет размер в байтах вместо элементов. Используйте этот вариант, только если размер не может быть выражен как элементы. Например, строки будут использовать _bytes_ вариант только в том случае, char если аналогичная функция, которая будет использоватьwchar_t.

  • _Out_writes_z_(s)

    Указатель на массив s элементов. Элементы не должны быть допустимыми в предварительном состоянии. В пост-состоянии элементы до конца null, которые должны присутствовать, должны быть допустимыми. Если размер известен в байтах, масштабируйте s по размеру элемента.

  • _Inout_updates_(s)

    _Inout_updates_bytes_(s)

    Указатель на массив, который является как чтением, так и записью в функцию. Это элементы размера s и допустимые в предварительном и пост-состоянии.

    Вариант _bytes_ предоставляет размер в байтах вместо элементов. Используйте этот вариант, только если размер не может быть выражен как элементы. Например, строки будут использовать _bytes_ вариант только в том случае, char если аналогичная функция, которая будет использоватьwchar_t.

  • _Inout_updates_z_(s)

    Указатель на массив, завершающийся значением NULL, и имеет известный размер. Элементы до конца null , которые должны присутствовать, должны быть допустимыми как в предварительном, так и в пост-состоянии. Предполагается, что значение в пост-состоянии отличается от значения в предварительном состоянии; включающее расположение конца null. Если размер известен в байтах, масштабируйте s по размеру элемента.

  • _Out_writes_to_(s,c)

    _Out_writes_bytes_to_(s,c)

    _Out_writes_all_(s)

    _Out_writes_bytes_all_(s)

    Указатель на массив s элементов. Элементы не должны быть допустимыми в предварительном состоянии. В пост-состоянии элементы до cэлемента -th должны быть допустимыми. Вариант _bytes_ можно использовать, если размер известен в байтах, а не количество элементов.

    Например:

    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)

    Указатель на массив, который как считывается, так и записывается функцией. Это элементы размера s , все из которых должны быть допустимыми в предварительном состоянии, и c элементы должны быть допустимыми в пост-состоянии.

    Вариант _bytes_ предоставляет размер в байтах вместо элементов. Используйте этот вариант, только если размер не может быть выражен как элементы. Например, строки будут использовать _bytes_ вариант только в том случае, char если аналогичная функция, которая будет использоватьwchar_t.

  • _Inout_updates_all_(s)

    _Inout_updates_bytes_all_(s)

    Указатель на массив, который как считывается, так и записывается функцией элементов размера s . Определяется как эквивалентный:

    _Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))

    Другими словами, каждый элемент, который существует в буфере до s в предварительном состоянии, действителен в предварительном и пост-состоянии.

    Вариант _bytes_ предоставляет размер в байтах вместо элементов. Используйте этот вариант, только если размер не может быть выражен как элементы. Например, строки будут использовать _bytes_ вариант только в том случае, char если аналогичная функция, которая будет использоватьwchar_t.

  • _In_reads_to_ptr_(p)

    Указатель на массив, для которого p - _Curr_ (т. е. минус_Curr_) является допустимым выражением. p Элементы, прежде чем p должны быть допустимыми в предварительном состоянии.

    Например:

    int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
    
  • _In_reads_to_ptr_z_(p)

    Указатель на массив, завершающийся значением NULL, p для которого выражение p - _Curr_ (т. е. минус_Curr_) является допустимым выражением. Элементы, прежде чем p должны быть допустимыми в предварительном состоянии.

  • _Out_writes_to_ptr_(p)

    Указатель на массив, для которого p - _Curr_ (т. е. минус_Curr_) является допустимым выражением. p Элементы, прежде чем p не должны быть допустимыми в предварительном состоянии и должны быть допустимыми в пост-состоянии.

  • _Out_writes_to_ptr_z_(p)

    Указатель на массив, завершающийся значением NULL, p для которого p - _Curr_ (т. е. минус_Curr_) является допустимым выражением. Элементы, прежде чем p не должны быть допустимыми в предварительном состоянии и должны быть допустимыми в пост-состоянии.

Необязательные параметры указателя

Если примечания параметра указателя включается _opt_, он указывает, что параметр может иметь значение NULL. В противном случае заметка ведет себя так же, как и версия, которая не включает _opt_. Ниже приведен список _opt_ вариантов заметок параметра указателя:

_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_

Параметры указателя вывода

Для параметров указателя вывода требуется специальная нотация для диамбигуации null в параметре и расположении с указанием указателя.

Заметки и описания

  • _Outptr_

    Параметр не может иметь значение NULL, и в пост-состоянии расположение, указываемое на расположение, не может иметь значение NULL и должно быть допустимым.

  • _Outptr_opt_

    Параметр может иметь значение NULL, но в пост-состоянии расположение, указываемое на расположение, не может иметь значение NULL и должно быть допустимым.

  • _Outptr_result_maybenull_

    Параметр не может иметь значение NULL, и в состоянии после состояния, на которое указывает расположение, может иметь значение NULL.

  • _Outptr_opt_result_maybenull_

    Параметр может иметь значение NULL, а в состоянии после состояния, на которое указывает расположение, может иметь значение NULL.

    В следующей таблице дополнительные подстроки вставляются в имя заметки для дальнейшего уточнения смысла заметки. Различные подстроки: _z, _COM_, _buffer_и _bytebuffer__to_.

Внимание

Если интерфейс, который вы заметаете, является COM, используйте com-форму этих заметок. Не используйте заметки COM с любым другим интерфейсом типа.

  • _Outptr_result_z_

    _Outptr_opt_result_z_

    _Outptr_result_maybenull_z_

    _Outptr_opt_result_maybenull_z_

    Возвращаемый указатель содержит заметку _Null_terminated_ .

  • _COM_Outptr_

    _COM_Outptr_opt_

    _COM_Outptr_result_maybenull_

    _COM_Outptr_opt_result_maybenull_

    Возвращаемый указатель имеет семантику COM, поэтому он несет _On_failure_ условие после того, как возвращаемый указатель имеет значение NULL.

  • _Outptr_result_buffer_(s)

    _Outptr_result_bytebuffer_(s)

    _Outptr_opt_result_buffer_(s)

    _Outptr_opt_result_bytebuffer_(s)

    Возвращаемый указатель указывает на допустимый буфер элементов размера 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)

    Возвращаемый указатель указывает на буфер элементов размера s или байтов, из которых первый c является допустимым.

Некоторые соглашения интерфейса предполагают, что выходные параметры будут иметь значение NULL при сбое. Кроме явно COM-кода, предпочтительны формы в следующей таблице. Для COM-кода используйте соответствующие COM-формы, перечисленные в предыдущем разделе.

  • _Result_nullonfailure_

    Изменяет другие заметки. Результат имеет значение NULL, если функция завершается ошибкой.

  • _Result_zeroonfailure_

    Изменяет другие заметки. Результат равен нулю, если функция завершается ошибкой.

  • _Outptr_result_nullonfailure_

    Возвращаемый указатель указывает на допустимый буфер, если функция выполнена успешно, или значение NULL, если функция завершается ошибкой. Эта заметка используется для не необязательных параметров.

  • _Outptr_opt_result_nullonfailure_

    Возвращаемый указатель указывает на допустимый буфер, если функция выполнена успешно, или значение NULL, если функция завершается ошибкой. Эта заметка является необязательным параметром.

  • _Outref_result_nullonfailure_

    Возвращаемый указатель указывает на допустимый буфер, если функция выполнена успешно, или значение NULL, если функция завершается ошибкой. Эта заметка предназначена для ссылочного параметра.

Параметры выходных ссылок

Для выходных параметров часто используется ссылочный параметр. Для простых параметров ссылки на выходные данные, например int&, _Out_ предоставляет правильную семантику. Тем не менее, если выходное значение является указателем, например, эквивалентные заметки указателя, напримерint *&_Outptr_ int **, не предоставляют правильную семантику. Чтобы кратко выразить семантику выходных ссылочных параметров для типов указателей, используйте следующие составные заметки:

Заметки и описания

  • _Outref_

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL.

  • _Outref_result_maybenull_

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в пост-состоянии.

  • _Outref_result_buffer_(s)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на допустимый буфер элементов размера s .

  • _Outref_result_bytebuffer_(s)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на допустимый буфер размера s байтов.

  • _Outref_result_buffer_to_(s, c)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на буфер s элементов, из которых первый c является допустимым.

  • _Outref_result_bytebuffer_to_(s, c)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на буфер байтов s , из которых первый c является допустимым.

  • _Outref_result_buffer_all_(s)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на допустимый буфер допустимых элементов размера s .

  • _Outref_result_bytebuffer_all_(s)

    Результат должен быть допустимым в пост-состоянии и не может иметь значение NULL. Указывает на допустимый s буфер байтов допустимых элементов.

  • _Outref_result_buffer_maybenull_(s)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в пост-состоянии. Указывает на допустимый буфер элементов размера s .

  • _Outref_result_bytebuffer_maybenull_(s)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в пост-состоянии. Указывает на допустимый буфер размера s байтов.

  • _Outref_result_buffer_to_maybenull_(s, c)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в пост-состоянии. Указывает на буфер s элементов, из которых первый c является допустимым.

  • _Outref_result_bytebuffer_to_maybenull_(s,c)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в состоянии после публикации. Указывает на буфер байтов s , из которых первый c является допустимым.

  • _Outref_result_buffer_all_maybenull_(s)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в состоянии после публикации. Указывает на допустимый буфер допустимых элементов размера s .

  • _Outref_result_bytebuffer_all_maybenull_(s)

    Результат должен быть допустимым в пост-состоянии, но может иметь значение NULL в состоянии после публикации. Указывает на допустимый s буфер байтов допустимых элементов.

Возвращаемые значения

Возвращаемое значение функции напоминает _Out_ параметр, но находится на другом уровне отмены ссылки, и вам не нужно учитывать концепцию указателя на результат. Для следующих заметок возвращаемое значение — это аннотированный объект — скалярный, указатель на структуру или указатель на буфер. Эти заметки имеют ту же семантику, что и соответствующая _Out_ заметка.

_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_

Форматирование строковых параметров

  • _Printf_format_string_ Указывает, что параметр является строкой формата для использования в printf выражении.

    Пример

    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_ Указывает, что параметр является строкой формата для использования в scanf выражении.

    Пример

    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_ Указывает, что параметр является строкой формата для использования в scanf_s выражении.

    Пример

    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;
    }
    

Другие распространенные заметки

Заметки и описания

  • _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)

    Параметр, поле или результат находится в диапазоне (включительно) от low .hi _Satisfies_(_Curr_ >= low && _Curr_ <= hi) Эквивалентно тому, что применяется к аннотированного объекта вместе с соответствующими условиями предварительного или пост-состояния.

    Внимание

    Хотя имена содержат "in" и "out", семантика _In_ и _Out_ не применяются к этим заметкам.

  • _Pre_equal_to_(expr)

    _Post_equal_to_(expr)

    Аннотированного значения точно expr. _Satisfies_(_Curr_ == expr) Эквивалентно тому, что применяется к аннотированного объекта вместе с соответствующими условиями предварительного или пост-состояния.

  • _Struct_size_bytes_(size)

    Применяется к объявлению структуры или класса. Указывает, что допустимый объект этого типа может быть больше объявленного типа с числом байтов, заданным size. Например:

    typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };

    Затем требуется размер буфера в байтах параметра pM типа MyStruct * :

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

См. также