Annoter les paramètres de fonction et les valeurs de retour
Cet article décrit les utilisations classiques d’annotations pour les paramètres de fonction simples ( scalaires et pointeurs vers des structures et des classes) et la plupart des types de mémoires tampons. Cet article présente également des modèles d’utilisation courants pour les annotations. Pour obtenir des annotations supplémentaires liées aux fonctions, consultez Le comportement de la fonction annoter.
Paramètres de pointeur
Pour les annotations du tableau suivant, lorsqu’un paramètre de pointeur est annoté, l’analyseur signale une erreur si le pointeur a la valeur Null. Cette annotation s’applique aux pointeurs et à tout élément de données vers lequel il pointe.
Annotations et descriptions
_In_
Annote les paramètres d’entrée qui sont des scalaires, des structures, des pointeurs vers des structures et des éléments similaires. Peut être utilisé explicitement sur des scalaires simples. Le paramètre doit être valide dans un état antérieur et ne sera pas modifié.
_Out_
Annote les paramètres de sortie qui sont des scalaires, des structures, des pointeurs vers des structures et des éléments similaires. N’appliquez pas cette annotation à un objet qui ne peut pas retourner de valeur, par exemple un scalaire passé par valeur. Le paramètre n’a pas besoin d’être valide en pré-état, mais doit être valide après l’état.
_Inout_
Annote un paramètre qui sera modifié par la fonction. Elle doit être valide à la fois dans un état antérieur et post-état, mais elle est supposée avoir des valeurs différentes avant et après l’appel. Doit s’appliquer à une valeur modifiable.
_In_z_
Pointeur vers une chaîne terminée par null utilisée comme entrée. La chaîne doit être valide dans un état antérieur. Les variantes de
PSTR
, qui ont déjà les annotations correctes, sont préférées._Inout_z_
Pointeur vers un tableau de caractères terminé par null qui sera modifié. Il doit être valide avant et après l’appel, mais il est supposé que la valeur a changé. Le point de terminaison Null peut être déplacé, mais seuls les éléments jusqu’à la fin null d’origine sont accessibles.
_In_reads_(s)
_In_reads_bytes_(s)
Pointeur vers un tableau, lu par la fonction. Le tableau est d’éléments de taille
s
, qui doivent tous être valides.La
_bytes_
variante donne la taille en octets au lieu d’éléments. Utilisez cette variante uniquement lorsque la taille ne peut pas être exprimée en tant qu’éléments. Par exemple,char
les chaînes n’utilisent la_bytes_
variante que si une fonction similaire utiliséewchar_t
est utilisée._In_reads_z_(s)
Pointeur vers un tableau qui est terminé par null et dont la taille est connue. Les éléments jusqu’à la marque de fin Null (ou
s
s’il n’y a pas de terminateur Null) doivent être valides en pré-état. Si la taille est connue en octets, mettez à l’échelles
la taille de l’élément._In_reads_or_z_(s)
Pointeur vers un tableau qui est terminé par null ou a une taille connue, ou les deux. Les éléments jusqu’à la marque de fin Null (ou
s
s’il n’y a pas de terminateur Null) doivent être valides en pré-état. Si la taille est connue en octets, mettez à l’échelles
la taille de l’élément. (Utilisé pour lastrn
famille.)_Out_writes_(s)
_Out_writes_bytes_(s)
Pointeur vers un tableau d’éléments
s
(résp. octets) qui seront écrits par la fonction. Les éléments de tableau n’ont pas besoin d’être valides en pré-état et le nombre d’éléments valides dans un état post-état n’est pas spécifié. S’il existe des annotations sur le type de paramètre, elles sont appliquées dans un état post-état. Par exemple, prenons le code suivant.typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
Dans cet exemple, l’appelant fournit une mémoire tampon d’éléments
size
pourp1
.MyStringCopy
rend certains de ces éléments valides. Plus important encore, l’annotation_Null_terminated_
surPWSTR
signifie qu’ellep1
est terminée par null après l’état. De cette façon, le nombre d’éléments valides est toujours bien défini, mais un nombre d’éléments spécifique n’est pas obligatoire.La
_bytes_
variante donne la taille en octets au lieu d’éléments. Utilisez cette variante uniquement lorsque la taille ne peut pas être exprimée en tant qu’éléments. Par exemple,char
les chaînes n’utilisent la_bytes_
variante que si une fonction similaire utiliséewchar_t
est utilisée._Out_writes_z_(s)
Pointeur vers un tableau d’éléments
s
. Les éléments n’ont pas besoin d’être valides en pré-état. Dans un état post-état, les éléments jusqu’à la fin null( qui doivent être présents) doivent être valides. Si la taille est connue en octets, mettez à l’échelles
la taille de l’élément._Inout_updates_(s)
_Inout_updates_bytes_(s)
Pointeur vers un tableau, qui est lu et écrit dans la fonction. Il s’agit d’éléments de taille
s
et valides en pré-état et en post-état.La
_bytes_
variante donne la taille en octets au lieu d’éléments. Utilisez cette variante uniquement lorsque la taille ne peut pas être exprimée en tant qu’éléments. Par exemple,char
les chaînes n’utilisent la_bytes_
variante que si une fonction similaire utiliséewchar_t
est utilisée._Inout_updates_z_(s)
Pointeur vers un tableau qui est terminé par null et dont la taille est connue. Les éléments jusqu’à la fin null( qui doivent être présents) doivent être valides à la fois en pré-état et en post-état. La valeur dans l’état post-état est supposée être différente de la valeur dans le pré-état ; qui inclut l’emplacement du terminateur Null. Si la taille est connue en octets, mettez à l’échelle
s
la taille de l’élément._Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
Pointeur vers un tableau d’éléments
s
. Les éléments n’ont pas besoin d’être valides en pré-état. Dans le post-état, les éléments jusqu’à -c
th élément doivent être valides. La_bytes_
variante peut être utilisée si la taille est connue en octets plutôt que le nombre d’éléments.Par exemple :
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)
Pointeur vers un tableau, qui est lu et écrit par la fonction. Il s’agit d’éléments de taille
s
, qui doivent tous être valides en pré-état, etc
les éléments doivent être valides après l’état.La
_bytes_
variante donne la taille en octets au lieu d’éléments. Utilisez cette variante uniquement lorsque la taille ne peut pas être exprimée en tant qu’éléments. Par exemple,char
les chaînes n’utilisent la_bytes_
variante que si une fonction similaire utiliséewchar_t
est utilisée._Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
Pointeur vers un tableau, qui est lu et écrit par la fonction d’éléments de taille
s
. Défini comme équivalent à :_Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))
En d’autres termes, chaque élément qui existe dans la mémoire tampon jusqu’à
s
l’état antérieur est valide dans l’état antérieur et après l’état.La
_bytes_
variante donne la taille en octets au lieu d’éléments. Utilisez cette variante uniquement lorsque la taille ne peut pas être exprimée en tant qu’éléments. Par exemple,char
les chaînes n’utilisent la_bytes_
variante que si une fonction similaire utiliséewchar_t
est utilisée._In_reads_to_ptr_(p)
Pointeur vers un tableau pour lequel
p - _Curr_
(autrement dit,p
moins_Curr_
) est une expression valide. Les éléments avantp
doivent être valides en pré-état.Par exemple :
int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
_In_reads_to_ptr_z_(p)
Pointeur vers un tableau terminé par null pour lequel l’expression
p - _Curr_
(autrement dit,p
moins_Curr_
) est une expression valide. Les éléments avantp
doivent être valides en pré-état._Out_writes_to_ptr_(p)
Pointeur vers un tableau pour lequel
p - _Curr_
(autrement dit,p
moins_Curr_
) est une expression valide. Les éléments avantp
n’ont pas besoin d’être valides en pré-état et doivent être valides après l’état._Out_writes_to_ptr_z_(p)
Pointeur vers un tableau terminé par null pour lequel
p - _Curr_
(autrement dit,p
moins_Curr_
) est une expression valide. Les éléments avantp
n’ont pas besoin d’être valides en pré-état et doivent être valides après l’état.
Paramètres de pointeur facultatifs
Lorsqu’une annotation de paramètre de pointeur inclut _opt_
, elle indique que le paramètre peut être null. Sinon, l’annotation se comporte de la même façon que la version qui n’inclut _opt_
pas . Voici une liste des variantes des _opt_
annotations de paramètre de pointeur :
_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_
Paramètres du pointeur de sortie
Les paramètres de pointeur de sortie nécessitent une notation spéciale pour lever l’ambiguïté de la valeur null sur le paramètre et l’emplacement pointu.
Annotations et descriptions
_Outptr_
Le paramètre ne peut pas être null et, dans l’état suivant, l’emplacement pointu ne peut pas être null et doit être valide.
_Outptr_opt_
Le paramètre peut être Null, mais dans l’état suivant, l’emplacement pointé ne peut pas être null et doit être valide.
_Outptr_result_maybenull_
Le paramètre ne peut pas être null et, dans l’état suivant, l’emplacement pointu peut avoir la valeur Null.
_Outptr_opt_result_maybenull_
Le paramètre peut être null et, dans l’état suivant, l’emplacement pointé peut être null.
Dans le tableau suivant, d’autres sous-chaînes sont insérées dans le nom de l’annotation pour qualifier davantage la signification de l’annotation. Les différentes sous-chaînes sont
_z
, ,_buffer_
_COM_
,_bytebuffer_
, et_to_
.
Important
Si l’interface que vous annotez est COM, utilisez la forme COM de ces annotations. N’utilisez pas les annotations COM avec une autre interface de type.
_Outptr_result_z_
_Outptr_opt_result_z_
_Outptr_result_maybenull_z_
_Outptr_opt_result_maybenull_z_
Le pointeur retourné a l’annotation
_Null_terminated_
._COM_Outptr_
_COM_Outptr_opt_
_COM_Outptr_result_maybenull_
_COM_Outptr_opt_result_maybenull_
Le pointeur retourné a une sémantique COM, c’est pourquoi il porte une
_On_failure_
condition post-condition que le pointeur retourné est null._Outptr_result_buffer_(s)
_Outptr_result_bytebuffer_(s)
_Outptr_opt_result_buffer_(s)
_Outptr_opt_result_bytebuffer_(s)
Le pointeur retourné pointe vers une mémoire tampon valide d’éléments de taille
s
ou d’octets._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)
Le pointeur retourné pointe vers une mémoire tampon d’éléments de taille
s
ou d’octets, dont le premierc
est valide.
Certaines conventions d’interface supposent que les paramètres de sortie sont nullifiés en cas d’échec. À l’exception du code COM explicitement, les formulaires du tableau suivant sont préférés. Pour le code COM, utilisez les formulaires COM correspondants répertoriés dans la section précédente.
_Result_nullonfailure_
Modifie d’autres annotations. Le résultat est défini sur Null si la fonction échoue.
_Result_zeroonfailure_
Modifie d’autres annotations. Le résultat est défini sur zéro si la fonction échoue.
_Outptr_result_nullonfailure_
Le pointeur retourné pointe vers une mémoire tampon valide si la fonction réussit ou null si la fonction échoue. Cette annotation concerne un paramètre non facultatif.
_Outptr_opt_result_nullonfailure_
Le pointeur retourné pointe vers une mémoire tampon valide si la fonction réussit ou null si la fonction échoue. Cette annotation concerne un paramètre facultatif.
_Outref_result_nullonfailure_
Le pointeur retourné pointe vers une mémoire tampon valide si la fonction réussit ou null si la fonction échoue. Cette annotation concerne un paramètre de référence.
Paramètres de référence de sortie
L’utilisation courante du paramètre de référence concerne les paramètres de sortie. Pour les paramètres de référence de sortie simples tels que int&
, _Out_
fournit la sémantique correcte. Toutefois, lorsque la valeur de sortie est un pointeur tel que int *&
, les annotations de pointeur équivalentes comme _Outptr_ int **
ne fournissent pas la sémantique correcte. Pour exprimer de manière concise la sémantique des paramètres de référence de sortie pour les types de pointeur, utilisez ces annotations composites :
Annotations et descriptions
_Outref_
Le résultat doit être valide après l’état et ne peut pas être null.
_Outref_result_maybenull_
Le résultat doit être valide après l’état, mais peut être null dans un état post-état.
_Outref_result_buffer_(s)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers la mémoire tampon valide des éléments de taille
s
._Outref_result_bytebuffer_(s)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers une mémoire tampon valide de taille
s
d’octets._Outref_result_buffer_to_(s, c)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers la mémoire tampon des
s
éléments dont le premierc
est valide._Outref_result_bytebuffer_to_(s, c)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers la mémoire tampon d’octets
s
dont le premierc
est valide._Outref_result_buffer_all_(s)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers la mémoire tampon valide des éléments valides de taille
s
._Outref_result_bytebuffer_all_(s)
Le résultat doit être valide après l’état et ne peut pas être null. Pointe vers une mémoire tampon valide d’octets d’éléments
s
valides._Outref_result_buffer_maybenull_(s)
Le résultat doit être valide après l’état, mais peut être null dans un état post-état. Pointe vers la mémoire tampon valide des éléments de taille
s
._Outref_result_bytebuffer_maybenull_(s)
Le résultat doit être valide après l’état, mais peut être null dans un état post-état. Pointe vers une mémoire tampon valide de taille
s
d’octets._Outref_result_buffer_to_maybenull_(s, c)
Le résultat doit être valide après l’état, mais peut être null dans un état post-état. Pointe vers la mémoire tampon des
s
éléments dont le premierc
est valide._Outref_result_bytebuffer_to_maybenull_(s,c)
Le résultat doit être valide après l’état, mais peut être null dans l’état post-état. Pointe vers la mémoire tampon d’octets
s
dont le premierc
est valide._Outref_result_buffer_all_maybenull_(s)
Le résultat doit être valide après l’état, mais peut être null dans l’état post-état. Pointe vers la mémoire tampon valide des éléments valides de taille
s
._Outref_result_bytebuffer_all_maybenull_(s)
Le résultat doit être valide après l’état, mais peut être null dans l’état post-état. Pointe vers une mémoire tampon valide d’octets d’éléments
s
valides.
Valeurs de retour
La valeur de retour d’une fonction ressemble à un _Out_
paramètre, mais se trouve à un niveau différent de référence, et vous n’avez pas à prendre en compte le concept du pointeur vers le résultat. Pour les annotations suivantes, la valeur de retour est l’objet annoté , un scalaire, un pointeur vers un struct ou un pointeur vers une mémoire tampon. Ces annotations ont la même sémantique que l’annotation correspondante _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_
Mettre en forme les paramètres de chaîne
_Printf_format_string_
Indique que le paramètre est une chaîne de format à utiliser dans uneprintf
expression.Exemple
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_
Indique que le paramètre est une chaîne de format à utiliser dans unescanf
expression.Exemple
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_
Indique que le paramètre est une chaîne de format à utiliser dans unescanf_s
expression.Exemple
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; }
Autres annotations courantes
Annotations et descriptions
_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)
Le paramètre, le champ ou le résultat se trouve dans la plage (inclusive) de
low
àhi
. Équivalent à_Satisfies_(_Curr_ >= low && _Curr_ <= hi)
celui-ci appliqué à l’objet annoté avec les conditions de pré-état ou post-état appropriées.Important
Bien que les noms contiennent « in » et « out », la sémantique de
_In_
ces annotations ne_Out_
s’applique pas et ne s’applique pas à ces annotations._Pre_equal_to_(expr)
_Post_equal_to_(expr)
La valeur annotée est exactement
expr
. Équivalent à_Satisfies_(_Curr_ == expr)
celui-ci appliqué à l’objet annoté avec les conditions de pré-état ou post-état appropriées._Struct_size_bytes_(size)
S’applique à une déclaration de struct ou de classe. Indique qu’un objet valide de ce type peut être supérieur au type déclaré, avec le nombre d’octets donné par
size
. Par exemple :typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
La taille de la mémoire tampon en octets d’un paramètre
pM
de typeMyStruct *
est ensuite prise comme suit :min(pM->nSize, sizeof(MyStruct))
Voir aussi
- Utilisation d’annotations SAL pour réduire les défauts du code C/C++
- Présentation de SAL
- Annotation du comportement d’une fonction
- Annotations des structs et des classes
- Annotation du comportement de verrouillage
- Spécification du moment et de l’endroit où une annotation s’applique
- Fonctions intrinsèques
- Bonnes pratiques et exemples