Kommentieren von Funktionsparametern und Rückgabewerten
In diesem Artikel werden typische Verwendungen von Anmerkungen für einfache Funktionsparameter – Skalare und Zeiger auf Strukturen und Klassen – und die meisten Arten von Puffern beschrieben. In diesem Artikel werden auch allgemeine Verwendungsmuster für Anmerkungen gezeigt. Weitere Anmerkungen zu Funktionen finden Sie unter Annotating function behavior.
Zeigerparameter
Für die Anmerkungen in der folgenden Tabelle meldet die Analyse einen Fehler, wenn ein Zeigerparameter kommentiert wird, wenn der Zeiger null ist. Diese Anmerkung gilt für Zeiger und für alle Datenelemente, auf die verwiesen wird.
Anmerkungen und Beschreibungen
_In_
Kommentiert Eingabeparameter, die Skalar, Strukturen, Zeiger auf Strukturen und ähnliches sind. Explizit kann für einfache Skalare verwendet werden. Der Parameter muss im Vorzustand gültig sein und wird nicht geändert.
_Out_
Kommentiert Ausgabeparameter, die Skalare, Strukturen, Zeiger auf Strukturen und ähnliches sind. Wenden Sie diese Anmerkung nicht auf ein Objekt an, das keinen Wert zurückgeben kann, z. B. einen Skalar, der nach Wert übergeben wird. Der Parameter muss nicht im Vorabzustand gültig sein, muss aber im Poststatus gültig sein.
_Inout_
Kommentiert einen Parameter, der von der Funktion geändert wird. Sie muss sowohl vor als auch nach dem Zustand gültig sein, wird jedoch davon ausgegangen, dass sie vor und nach dem Aufruf unterschiedliche Werte aufweist. Muss auf einen modifizierbaren Wert angewendet werden.
_In_z_
Ein Zeiger auf eine mit Null beendete Zeichenfolge, die als Eingabe verwendet wird. Die Zeichenfolge muss im Vorzustand gültig sein. Varianten von
PSTR
, die bereits über die richtigen Anmerkungen verfügen, werden bevorzugt._Inout_z_
Ein Zeiger auf ein null-beendetes Zeichenarray, das geändert wird. Er muss vor und nach dem Aufruf gültig sein, aber es wird davon ausgegangen, dass sich der Wert geändert hat. Der Null-Terminator kann verschoben werden, aber nur auf die Elemente bis zum ursprünglichen Null-Terminator kann zugegriffen werden.
_In_reads_(s)
_In_reads_bytes_(s)
Ein Zeiger auf ein Array, das von der Funktion gelesen wird. Das Array weist Größenelemente
s
auf, die alle gültig sein müssen.Die
_bytes_
Variante gibt die Größe in Bytes anstelle von Elementen an. Verwenden Sie diese Variante nur, wenn die Größe nicht als Elemente ausgedrückt werden kann. Beispielsweise würden Zeichenfolgen die_bytes_
Variante nur verwenden,char
wenn eine ähnliche Funktion, die verwendet wird, verwendetwchar_t
würde._In_reads_z_(s)
Ein Zeiger auf ein Array, das null beendet ist und eine bekannte Größe aufweist. Die Elemente bis zum Null-Endator ( oder
s
wenn kein Null-Terminator vorhanden ist ) müssen im Vorzustand gültig sein. Wenn die Größe in Byte bekannt ist, skalieren Sies
die Elementgröße._In_reads_or_z_(s)
Ein Zeiger auf ein Array, das null beendet ist oder eine bekannte Größe aufweist oder beides hat. Die Elemente bis zum Null-Endator ( oder
s
wenn kein Null-Terminator vorhanden ist ) müssen im Vorzustand gültig sein. Wenn die Größe in Byte bekannt ist, skalieren Sies
die Elementgröße. (Wird für diestrn
Familie verwendet.)_Out_writes_(s)
_Out_writes_bytes_(s)
Ein Zeiger auf ein Array von
s
Elementen (bzw. Byte), das von der Funktion geschrieben wird. Die Arrayelemente müssen nicht im Vorabzustand gültig sein, und die Anzahl der Elemente, die nach dem Status gültig sind, ist nicht angegeben. Wenn anmerkungen für den Parametertyp vorhanden sind, werden sie nach dem Zustand angewendet. Betrachten Sie hierzu den folgenden Beispielcode:typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
In diesem Beispiel stellt der Aufrufer einen Puffer von
size
Elementen fürp1
.MyStringCopy
macht einige dieser Elemente gültig. Wichtiger ist, dass die_Null_terminated_
Anmerkung angibtPWSTR
, dassp1
im Postzustand null-beendet ist. Auf diese Weise ist die Anzahl der gültigen Elemente noch gut definiert, aber eine bestimmte Elementanzahl ist nicht erforderlich.Die
_bytes_
Variante gibt die Größe in Bytes anstelle von Elementen an. Verwenden Sie diese Variante nur, wenn die Größe nicht als Elemente ausgedrückt werden kann. Beispielsweise würden Zeichenfolgen die_bytes_
Variante nur verwenden,char
wenn eine ähnliche Funktion, die verwendet wird, verwendetwchar_t
würde._Out_writes_z_(s)
Ein Zeiger auf ein Array von
s
Elementen. Die Elemente müssen nicht im Vorabzustand gültig sein. In post-state müssen die Elemente über den Null-Endator (die vorhanden sein müssen) gültig sein. Wenn die Größe in Byte bekannt ist, skalieren Sies
die Elementgröße._Inout_updates_(s)
_Inout_updates_bytes_(s)
Ein Zeiger auf ein Array, das sowohl gelesen als auch in die Funktion geschrieben wird. Es ist von Größenelementen
s
und gültig im Vor- und Nachzustand.Die
_bytes_
Variante gibt die Größe in Bytes anstelle von Elementen an. Verwenden Sie diese Variante nur, wenn die Größe nicht als Elemente ausgedrückt werden kann. Beispielsweise würden Zeichenfolgen die_bytes_
Variante nur verwenden,char
wenn eine ähnliche Funktion, die verwendet wird, verwendetwchar_t
würde._Inout_updates_z_(s)
Ein Zeiger auf ein Array, das null beendet ist und eine bekannte Größe aufweist. Die Elemente bis zum Null-Endator ( die vorhanden sein müssen ) müssen sowohl im Vorzustand als auch nach dem Zustand gültig sein. Der Wert im Postzustand wird davon ausgegangen, dass er sich vom Wert im Vorzustand unterscheidet; die die Position des Null-Terminators enthält. Wenn die Größe in Byte bekannt ist, skalieren Sie
s
die Elementgröße._Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
Ein Zeiger auf ein Array von
s
Elementen. Die Elemente müssen nicht im Vorabzustand gültig sein. Im Poststatus müssen die Elemente bis zumc
-th-Element gültig sein. Die_bytes_
Variante kann verwendet werden, wenn die Größe in Bytes und nicht in der Anzahl der Elemente bekannt ist.Beispiel:
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)
Ein Zeiger auf ein Array, das von der Funktion gelesen und geschrieben wird. Es gibt Größenelemente
s
, die alle im Vorzustand gültig sein müssen, undc
Elemente müssen nach dem Zustand gültig sein.Die
_bytes_
Variante gibt die Größe in Bytes anstelle von Elementen an. Verwenden Sie diese Variante nur, wenn die Größe nicht als Elemente ausgedrückt werden kann. Beispielsweise würden Zeichenfolgen die_bytes_
Variante nur verwenden,char
wenn eine ähnliche Funktion, die verwendet wird, verwendetwchar_t
würde._Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
Ein Zeiger auf ein Array, das sowohl von der Funktion der Größenelemente
s
gelesen als auch geschrieben wird. Definiert als Äquivalent zu:_Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))
Mit anderen Worten: Jedes Element, das im Puffer bis zum
s
Vorzustand vorhanden ist, ist im Vor- und Nachzustand gültig.Die
_bytes_
Variante gibt die Größe in Bytes anstelle von Elementen an. Verwenden Sie diese Variante nur, wenn die Größe nicht als Elemente ausgedrückt werden kann. Beispielsweise würden Zeichenfolgen die_bytes_
Variante nur verwenden,char
wenn eine ähnliche Funktion, die verwendet wird, verwendetwchar_t
würde._In_reads_to_ptr_(p)
Ein Zeiger auf ein Array, für das
p - _Curr_
(d. hp
. minus_Curr_
) ein gültiger Ausdruck ist. Die Elemente vorp
dem Status müssen im Voraus gültig sein.Beispiel:
int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
_In_reads_to_ptr_z_(p)
Ein Zeiger auf ein null-beendetes Array, für das ein Ausdruck
p - _Curr_
(d. hp
. minus_Curr_
) ein gültiger Ausdruck ist. Die Elemente vorp
dem Status müssen im Voraus gültig sein._Out_writes_to_ptr_(p)
Ein Zeiger auf ein Array, für das
p - _Curr_
(d. hp
. minus_Curr_
) ein gültiger Ausdruck ist. Die Elemente, bevorp
sie nicht im Vorabzustand gültig sein müssen und nach dem Status gültig sein müssen._Out_writes_to_ptr_z_(p)
Ein Zeiger auf ein null-beendetes Array, für das
p - _Curr_
(d. hp
. minus_Curr_
) ein gültiger Ausdruck ist. Die Elemente, bevorp
sie nicht im Vorabzustand gültig sein müssen und nach dem Status gültig sein müssen.
Optionale Zeigerparameter
Wenn eine Zeigerparameteranmerkung enthält _opt_
, gibt sie an, dass der Parameter null sein kann. Andernfalls verhält sich die Anmerkung genauso wie die Version, die nicht enthalten _opt_
ist. Hier ist eine Liste der _opt_
Varianten der Zeigerparameteranmerkungen:
_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_
Ausgabezeigerparameter
Ausgabezeigerparameter erfordern eine spezielle Schreibweise, um die Nullwerte für den Parameter und die Zeigerposition zu disambiguieren.
Anmerkungen und Beschreibungen
_Outptr_
Der Parameter darf nicht null sein, und im Postzustand darf der Point-to-Location nicht null sein und muss gültig sein.
_Outptr_opt_
Der Parameter kann null sein, aber im Postzustand darf der Point-to-Speicherort nicht null sein und muss gültig sein.
_Outptr_result_maybenull_
Der Parameter darf nicht null sein, und im Postzustand kann der Point-to-Location null sein.
_Outptr_opt_result_maybenull_
Der Parameter kann null sein, und im Postzustand kann der Point-to-Location null sein.
In der folgenden Tabelle werden zusätzliche Teilzeichenfolgen in den Anmerkungsnamen eingefügt, um die Bedeutung der Anmerkung weiter zu qualifizieren. Die verschiedenen Teilzeichenfolgen sind
_z
, ,_COM_
,_buffer_
,_bytebuffer_
und_to_
.
Wichtig
Wenn die Schnittstelle, die Sie kommentieren, COM ist, verwenden Sie die COM-Form dieser Anmerkungen. Verwenden Sie die COM-Anmerkungen nicht mit einer anderen Typschnittstelle.
_Outptr_result_z_
_Outptr_opt_result_z_
_Outptr_result_maybenull_z_
_Outptr_opt_result_maybenull_z_
Der zurückgegebene Zeiger weist die
_Null_terminated_
Anmerkung auf._COM_Outptr_
_COM_Outptr_opt_
_COM_Outptr_result_maybenull_
_COM_Outptr_opt_result_maybenull_
Der zurückgegebene Zeiger verfügt über COM-Semantik, weshalb er eine
_On_failure_
Postbedingung trägt, dass der zurückgegebene Zeiger null ist._Outptr_result_buffer_(s)
_Outptr_result_bytebuffer_(s)
_Outptr_opt_result_buffer_(s)
_Outptr_opt_result_bytebuffer_(s)
Der zurückgegebene Zeiger verweist auf einen gültigen Puffer von Größenelementen
s
oder 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)
Der zurückgegebene Zeiger verweist auf einen Puffer von Größenelementen
s
oder Bytes, von denen der erstec
gültig ist.
Bei bestimmten Schnittstellenkonventionen wird davon ausgegangen, dass Ausgabeparameter beim Fehler nullifiziert werden. Mit Ausnahme expliziter COM-Code werden die Formulare in der folgenden Tabelle bevorzugt. Verwenden Sie für COM-Code die entsprechenden COM-Formulare, die im vorherigen Abschnitt aufgeführt sind.
_Result_nullonfailure_
Ändert andere Anmerkungen. Das Ergebnis wird auf NULL festgelegt, wenn die Funktion fehlschlägt.
_Result_zeroonfailure_
Ändert andere Anmerkungen. Das Ergebnis wird auf Null festgelegt, wenn die Funktion fehlschlägt.
_Outptr_result_nullonfailure_
Der zurückgegebene Zeiger verweist auf einen gültigen Puffer, wenn die Funktion erfolgreich ist, oder null, wenn die Funktion fehlschlägt. Diese Anmerkung ist für einen nicht optionalen Parameter vorgesehen.
_Outptr_opt_result_nullonfailure_
Der zurückgegebene Zeiger verweist auf einen gültigen Puffer, wenn die Funktion erfolgreich ist, oder null, wenn die Funktion fehlschlägt. Diese Anmerkung ist für einen optionalen Parameter vorgesehen.
_Outref_result_nullonfailure_
Der zurückgegebene Zeiger verweist auf einen gültigen Puffer, wenn die Funktion erfolgreich ist, oder null, wenn die Funktion fehlschlägt. Diese Anmerkung ist für einen Referenzparameter vorgesehen.
Ausgabereferenzparameter
Eine häufige Verwendung des Referenzparameters ist für Ausgabeparameter. Für einfache Ausgabereferenzparameter wie int&
z _Out_
. B. stellt die richtige Semantik bereit. Wenn der Ausgabewert jedoch ein Zeiger ist, z int *&
. B. , stellen die entsprechenden Zeigeranmerkungen die _Outptr_ int **
richtige Semantik nicht bereit. Verwenden Sie die folgenden zusammengesetzten Anmerkungen, um die Semantik der Ausgabereferenzparameter für Zeigertypen präzise auszudrücken:
Anmerkungen und Beschreibungen
_Outref_
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein.
_Outref_result_maybenull_
Das Ergebnis muss nach dem Status gültig sein, kann aber im Postzustand null sein.
_Outref_result_buffer_(s)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf einen gültigen Puffer von Größenelementen
s
._Outref_result_bytebuffer_(s)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf den gültigen Puffer der Größe
s
byte._Outref_result_buffer_to_(s, c)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf den Puffer von
s
Elementen, von denen der erstec
gültig ist._Outref_result_bytebuffer_to_(s, c)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf den Puffer von
s
Bytes, von denen der erstec
gültig ist._Outref_result_buffer_all_(s)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf den gültigen Puffer gültiger Elemente der Größe
s
._Outref_result_bytebuffer_all_(s)
Das Ergebnis muss im Postzustand gültig sein und darf nicht null sein. Verweist auf den gültigen Puffer von
s
Bytes gültiger Elemente._Outref_result_buffer_maybenull_(s)
Das Ergebnis muss nach dem Status gültig sein, kann aber im Postzustand null sein. Verweist auf einen gültigen Puffer von Größenelementen
s
._Outref_result_bytebuffer_maybenull_(s)
Das Ergebnis muss nach dem Status gültig sein, kann aber im Postzustand null sein. Verweist auf den gültigen Puffer der Größe
s
byte._Outref_result_buffer_to_maybenull_(s, c)
Das Ergebnis muss nach dem Status gültig sein, kann aber im Postzustand null sein. Verweist auf den Puffer von
s
Elementen, von denen der erstec
gültig ist._Outref_result_bytebuffer_to_maybenull_(s,c)
Das Ergebnis muss im Poststatus gültig sein, kann aber im Poststatus null sein. Verweist auf den Puffer von
s
Bytes, von denen der erstec
gültig ist._Outref_result_buffer_all_maybenull_(s)
Das Ergebnis muss im Poststatus gültig sein, kann aber im Poststatus null sein. Verweist auf den gültigen Puffer gültiger Elemente der Größe
s
._Outref_result_bytebuffer_all_maybenull_(s)
Das Ergebnis muss im Poststatus gültig sein, kann aber im Poststatus null sein. Verweist auf den gültigen Puffer von
s
Bytes gültiger Elemente.
Rückgabewerte
Der Rückgabewert einer Funktion ähnelt einem _Out_
Parameter, befindet sich jedoch auf einer anderen Ebene des Deverweises, und Sie müssen das Konzept des Zeigers auf das Ergebnis nicht berücksichtigen. Bei den folgenden Anmerkungen ist der Rückgabewert das kommentierte Objekt – ein Skalar, ein Zeiger auf eine Struktur oder ein Zeiger auf einen Puffer. Diese Anmerkungen weisen dieselbe Semantik wie die entsprechende _Out_
Anmerkung auf.
_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_
Formatzeichenfolgenparameter
_Printf_format_string_
Gibt an, dass der Parameter eine Formatzeichenfolge für die Verwendung in einemprintf
Ausdruck ist.Beispiel
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_
Gibt an, dass der Parameter eine Formatzeichenfolge für die Verwendung in einemscanf
Ausdruck ist.Beispiel
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_
Gibt an, dass der Parameter eine Formatzeichenfolge für die Verwendung in einemscanf_s
Ausdruck ist.Beispiel
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; }
Andere allgemeine Anmerkungen
Anmerkungen und Beschreibungen
_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)
Der Parameter, das Feld oder das Ergebnis befindet sich im Bereich (einschließlich) von
low
bis .hi
Entspricht dem_Satisfies_(_Curr_ >= low && _Curr_ <= hi)
, der zusammen mit den entsprechenden Bedingungen vor dem Zustand oder nach dem Zustand auf das kommentierte Objekt angewendet wird.Wichtig
Obwohl die Namen "in" und "out" enthalten, gelten die Semantik von
_In_
und_Out_
gelten nicht für diese Anmerkungen._Pre_equal_to_(expr)
_Post_equal_to_(expr)
Der kommentierte Wert ist genau
expr
. Entspricht dem_Satisfies_(_Curr_ == expr)
, der zusammen mit den entsprechenden Bedingungen vor dem Zustand oder nach dem Zustand auf das kommentierte Objekt angewendet wird._Struct_size_bytes_(size)
Gilt für eine Struktur- oder Klassendeklaration. Gibt an, dass ein gültiges Objekt dieses Typs größer als der deklarierte Typ sein kann, wobei die Anzahl der Byte
size
angegeben wird. Beispiel:typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
Die Puffergröße in Byte eines
pM
TypparametersMyStruct *
wird dann wie folgt übernommen:min(pM->nSize, sizeof(MyStruct))
Siehe auch
- Verwenden von SAL-Anmerkungen zum Reduzieren von C/C++-Codefehlern
- Einführung in SAL
- Hinzufügen einer Anmerkung zum Funktionsverhalten
- Hinzufügen einer Anmerkung zu Strukturen und Klassen
- Hinzufügen einer Anmerkung zum Sperrverhalten
- Angeben, wann und wo eine Anmerkung gültig ist
- Systeminterne Funktionen
- Empfohlene Vorgehensweisen und Beispiele