Dodawanie adnotacji do parametrów funkcji i zwracanych wartości
W tym artykule opisano typowe zastosowania adnotacji dla prostych parametrów funkcji — skalarnych i wskaźników do struktur i klas — oraz większości rodzajów. W tym artykule przedstawiono również typowe wzorce użycia adnotacji. Aby uzyskać dodatkowe adnotacje związane z funkcjami, zobacz Dodawanie adnotacji do zachowania funkcji.
Parametry wskaźnika
W przypadku adnotacji w poniższej tabeli, gdy parametr wskaźnika jest adnotacją, analizator zgłasza błąd, jeśli wskaźnik ma wartość null. Ta adnotacja ma zastosowanie do wskaźników i do każdego wskazywanego elementu danych.
Adnotacje i opisy
_In_
Dodawać adnotacje do parametrów wejściowych, które są skalarne, struktury, wskaźniki do struktur i podobne. Jawnie można używać w prostych skalarach. Parametr musi być prawidłowy w stanie wstępnym i nie zostanie zmodyfikowany.
_Out_
Dodawać adnotacje do parametrów wyjściowych, które są skalarne, struktury, wskaźniki do struktur i podobne. Nie stosuj tej adnotacji do obiektu, który nie może zwrócić wartości — na przykład skalarny przekazywany przez wartość. Parametr nie musi być prawidłowy w stanie wstępnym, ale musi być prawidłowy po stanie.
_Inout_
Dodawać adnotacje do parametru, który zostanie zmieniony przez funkcję . Musi być prawidłowy zarówno w stanie wstępnym, jak i po nim, ale przyjmuje się, że ma różne wartości przed wywołaniem i po nim. Należy zastosować wartość modyfikowalną.
_In_z_
Wskaźnik do ciągu zakończonego wartością null, który jest używany jako dane wejściowe. Ciąg musi być prawidłowy w stanie wstępnym. Preferowane są warianty elementów
PSTR
, które mają już poprawne adnotacje._Inout_z_
Wskaźnik do tablicy znaków zakończonej wartością null, która zostanie zmodyfikowana. Musi być prawidłowy przed wywołaniem i po wywołaniu, ale zakłada się, że wartość została zmieniona. Można przenieść terminator o wartości null, ale dostęp do oryginalnego terminatora o wartości null można uzyskać tylko do elementów.
_In_reads_(s)
_In_reads_bytes_(s)
Wskaźnik do tablicy, który jest odczytywany przez funkcję. Tablica ma rozmiar
s
elementów, z których wszystkie muszą być prawidłowe.Wariant
_bytes_
daje rozmiar w bajtach zamiast elementów. Użyj tego wariantu tylko wtedy, gdy rozmiar nie może być wyrażony jako elementy. Na przykład ciągi będą używać wariantu_bytes_
tylko wtedy,char
gdy podobna funkcja, która będzie używaćwchar_t
._In_reads_z_(s)
Wskaźnik do tablicy, która jest zakończona wartością null i ma znany rozmiar. Elementy do terminatora o wartości null lub
s
jeśli nie istnieje terminator o wartości null, muszą być prawidłowe w stanie wstępnym. Jeśli rozmiar jest znany w bajtach, skalujs
według rozmiaru elementu._In_reads_or_z_(s)
Wskaźnik do tablicy, która jest zakończona wartością null lub ma znany rozmiar lub oba te elementy. Elementy do terminatora o wartości null lub
s
jeśli nie istnieje terminator o wartości null, muszą być prawidłowe w stanie wstępnym. Jeśli rozmiar jest znany w bajtach, skalujs
według rozmiaru elementu. (Używane dlastrn
rodziny)._Out_writes_(s)
_Out_writes_bytes_(s)
Wskaźnik do tablicy
s
elementów (resp. bytes), które zostaną zapisane przez funkcję. Elementy tablicy nie muszą być prawidłowe w stanie wstępnym, a liczba elementów prawidłowych w stanie po stanie jest nieokreślona. Jeśli w typie parametru istnieją adnotacje, są one stosowane po stanie. Rozważmy na przykład następujący kod.typedef _Null_terminated_ wchar_t *PWSTR; void MyStringCopy(_Out_writes_(size) PWSTR p1, _In_ size_t size, _In_ PWSTR p2);
W tym przykładzie obiekt wywołujący udostępnia bufor
size
elementów dla elementup1
.MyStringCopy
sprawia, że niektóre z tych elementów są prawidłowe. Co ważniejsze, adnotacja_Null_terminated_
oznaczaPWSTR
, żep1
wartość null kończy się po stanie. W ten sposób liczba prawidłowych elementów jest nadal dobrze zdefiniowana, ale określona liczba elementów nie jest wymagana.Wariant
_bytes_
daje rozmiar w bajtach zamiast elementów. Użyj tego wariantu tylko wtedy, gdy rozmiar nie może być wyrażony jako elementy. Na przykład ciągi będą używać wariantu_bytes_
tylko wtedy,char
gdy podobna funkcja, która będzie używaćwchar_t
._Out_writes_z_(s)
Wskaźnik do tablicy
s
elementów. Elementy nie muszą być prawidłowe w stanie wstępnym. W stanie po awarii elementy w górę przez terminator o wartości null — który musi być obecny — muszą być prawidłowe. Jeśli rozmiar jest znany w bajtach, skalujs
według rozmiaru elementu._Inout_updates_(s)
_Inout_updates_bytes_(s)
Wskaźnik do tablicy, który jest zarówno odczytywany, jak i zapisywany w funkcji. Jest to elementy rozmiaru
s
i prawidłowe w stanie wstępnym i po stanie.Wariant
_bytes_
daje rozmiar w bajtach zamiast elementów. Użyj tego wariantu tylko wtedy, gdy rozmiar nie może być wyrażony jako elementy. Na przykład ciągi będą używać wariantu_bytes_
tylko wtedy,char
gdy podobna funkcja, która będzie używaćwchar_t
._Inout_updates_z_(s)
Wskaźnik do tablicy, która jest zakończona wartością null i ma znany rozmiar. Elementy w górę przez terminator o wartości null — które muszą być obecne — muszą być prawidłowe zarówno w stanie wstępnym, jak i po stanie. Przyjmuje się, że wartość w stanie post-state różni się od wartości w stanie wstępnym; zawiera lokalizację terminatora o wartości null. Jeśli rozmiar jest znany w bajtach, skaluj
s
według rozmiaru elementu._Out_writes_to_(s,c)
_Out_writes_bytes_to_(s,c)
_Out_writes_all_(s)
_Out_writes_bytes_all_(s)
Wskaźnik do tablicy
s
elementów. Elementy nie muszą być prawidłowe w stanie wstępnym. Po stanie elementy doc
-th muszą być prawidłowe. Wariant_bytes_
może być używany, jeśli rozmiar jest znany w bajtach, a nie w liczbie elementów.Na przykład:
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)
Wskaźnik do tablicy, który jest zarówno odczytywany, jak i zapisywany przez funkcję. Jest to elementy rozmiaru
s
, z których wszystkie muszą być prawidłowe w stanie wstępnym, ac
elementy muszą być prawidłowe po stanie.Wariant
_bytes_
daje rozmiar w bajtach zamiast elementów. Użyj tego wariantu tylko wtedy, gdy rozmiar nie może być wyrażony jako elementy. Na przykład ciągi będą używać wariantu_bytes_
tylko wtedy,char
gdy podobna funkcja, która będzie używaćwchar_t
._Inout_updates_all_(s)
_Inout_updates_bytes_all_(s)
Wskaźnik do tablicy, który jest zarówno odczytywany, jak i zapisywany przez funkcję elementów rozmiaru
s
. Zdefiniowano jako odpowiednik:_Inout_updates_to_(_Old_(s), _Old_(s)) _Inout_updates_bytes_to_(_Old_(s), _Old_(s))
Innymi słowy, każdy element, który istnieje w buforze do
s
wstępnego stanu, jest prawidłowy w stanie wstępnym i po stanie.Wariant
_bytes_
daje rozmiar w bajtach zamiast elementów. Użyj tego wariantu tylko wtedy, gdy rozmiar nie może być wyrażony jako elementy. Na przykład ciągi będą używać wariantu_bytes_
tylko wtedy,char
gdy podobna funkcja, która będzie używaćwchar_t
._In_reads_to_ptr_(p)
Wskaźnik do tablicy,
p
dla którejp - _Curr_
(czyli minus_Curr_
) jest prawidłowym wyrażeniem. Elementy przedp
muszą być prawidłowe w stanie wstępnym.Na przykład:
int ReadAllElements(_In_reads_to_ptr_(EndOfArray) const int *Array, const int *EndOfArray);
_In_reads_to_ptr_z_(p)
Wskaźnik do tablicy zakończonej wartością null,
p
dla której wyrażeniep - _Curr_
(czyli minus_Curr_
) jest prawidłowym wyrażeniem. Elementy przedp
muszą być prawidłowe w stanie wstępnym._Out_writes_to_ptr_(p)
Wskaźnik do tablicy,
p
dla którejp - _Curr_
(czyli minus_Curr_
) jest prawidłowym wyrażeniem. Elementy, które niep
muszą być prawidłowe w stanie wstępnym i muszą być prawidłowe po stanie._Out_writes_to_ptr_z_(p)
Wskaźnik do tablicy zakończonej wartością null,
p
dla którejp - _Curr_
(czyli minus_Curr_
) jest prawidłowym wyrażeniem. Elementy, które niep
muszą być prawidłowe w stanie wstępnym i muszą być prawidłowe po stanie.
Opcjonalne parametry wskaźnika
Gdy adnotacja parametru wskaźnika zawiera _opt_
wartość , wskazuje, że parametr może mieć wartość null. W przeciwnym razie adnotacja zachowuje się tak samo jak wersja, która nie zawiera _opt_
elementu . Oto lista _opt_
wariantów adnotacji parametru wskaźnika:
_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_
Parametry wskaźnika wyjściowego
Parametry wskaźnika wyjściowego wymagają specjalnej notacji w celu uściślania wartości null parametru i wskazywanej lokalizacji.
Adnotacje i opisy
_Outptr_
Parametr nie może mieć wartości null, a po stanie wskazująca lokalizacja nie może mieć wartości null i musi być prawidłowa.
_Outptr_opt_
Parametr może mieć wartość null, ale po stanie wskazywana lokalizacja nie może mieć wartości null i musi być prawidłowa.
_Outptr_result_maybenull_
Parametr nie może mieć wartości null, a po stanie wskazywana lokalizacja może mieć wartość null.
_Outptr_opt_result_maybenull_
Parametr może mieć wartość null, a po stanie wskazywana lokalizacja może mieć wartość null.
W poniższej tabeli dodatkowe podciągy są wstawione do nazwy adnotacji, aby dodatkowo zakwalifikować znaczenie adnotacji. Różne podciągniki to
_z
, ,_buffer_
_COM_
,_bytebuffer_
, i_to_
.
Ważne
Jeśli interfejs, który jest adnotacją, jest COM, użyj formularza COM tych adnotacji. Nie używaj adnotacji COM z innym interfejsem typu.
_Outptr_result_z_
_Outptr_opt_result_z_
_Outptr_result_maybenull_z_
_Outptr_opt_result_maybenull_z_
Zwrócony wskaźnik ma adnotację
_Null_terminated_
._COM_Outptr_
_COM_Outptr_opt_
_COM_Outptr_result_maybenull_
_COM_Outptr_opt_result_maybenull_
Zwrócony wskaźnik ma semantykę COM, dlatego niesie ze sobą
_On_failure_
warunek po, że zwrócony wskaźnik ma wartość null._Outptr_result_buffer_(s)
_Outptr_result_bytebuffer_(s)
_Outptr_opt_result_buffer_(s)
_Outptr_opt_result_bytebuffer_(s)
Zwrócony wskaźnik wskazuje prawidłowy bufor elementów rozmiaru
s
lub bajtów._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)
Zwrócony wskaźnik wskazuje bufor elementów rozmiaru
s
lub bajtów, z których pierwszac
jest prawidłowa.
Niektóre konwencje interfejsu zakładają, że parametry wyjściowe są zerowe w przypadku awarii. Z wyjątkiem jawnego kodu COM, preferowane są formularze w poniższej tabeli. W przypadku kodu COM użyj odpowiednich formularzy COM wymienionych w poprzedniej sekcji.
_Result_nullonfailure_
Modyfikuje inne adnotacje. Wynik jest ustawiony na wartość null, jeśli funkcja zakończy się niepowodzeniem.
_Result_zeroonfailure_
Modyfikuje inne adnotacje. Wynik jest ustawiony na zero, jeśli funkcja zakończy się niepowodzeniem.
_Outptr_result_nullonfailure_
Zwrócony wskaźnik wskazuje prawidłowy bufor, jeśli funkcja powiedzie się lub null, jeśli funkcja zakończy się niepowodzeniem. Ta adnotacja dotyczy parametru innego niż opcjonalny.
_Outptr_opt_result_nullonfailure_
Zwrócony wskaźnik wskazuje prawidłowy bufor, jeśli funkcja powiedzie się lub null, jeśli funkcja zakończy się niepowodzeniem. Ta adnotacja dotyczy opcjonalnego parametru.
_Outref_result_nullonfailure_
Zwrócony wskaźnik wskazuje prawidłowy bufor, jeśli funkcja powiedzie się lub null, jeśli funkcja zakończy się niepowodzeniem. Ta adnotacja dotyczy parametru referencyjnego.
Parametry odwołania wyjściowego
Typowym zastosowaniem parametru referencyjnego jest parametr wyjściowy. W przypadku prostych parametrów referencyjnych danych wyjściowych, takich jak int&
, _Out_
zapewnia poprawną semantyka. Jeśli jednak wartość wyjściowa jest wskaźnikiem, takim jak , równoważne adnotacje wskaźnika, takie jak int *&
_Outptr_ int **
nie zapewniają poprawnej semantyki. Aby zwięzłie wyrazić semantyka parametrów referencyjnych danych wyjściowych dla typów wskaźników, użyj następujących adnotacji złożonych:
Adnotacje i opisy
_Outref_
Wynik musi być prawidłowy po stanie i nie może mieć wartości null.
_Outref_result_maybenull_
Wynik musi być prawidłowy po stanie, ale może mieć wartość null po stanie.
_Outref_result_buffer_(s)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje prawidłowy bufor elementów rozmiaru
s
._Outref_result_bytebuffer_(s)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje prawidłowy bufor rozmiaru
s
bajtów._Outref_result_buffer_to_(s, c)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje bufor
s
elementów, z których pierwszac
jest prawidłowa._Outref_result_bytebuffer_to_(s, c)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje bufor bajtów
s
, z których pierwszac
jest prawidłowa._Outref_result_buffer_all_(s)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje prawidłowy bufor prawidłowego rozmiaru
s
elementów._Outref_result_bytebuffer_all_(s)
Wynik musi być prawidłowy po stanie i nie może mieć wartości null. Wskazuje prawidłowy bufor bajtów
s
prawidłowych elementów._Outref_result_buffer_maybenull_(s)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null po stanie. Wskazuje prawidłowy bufor elementów rozmiaru
s
._Outref_result_bytebuffer_maybenull_(s)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null po stanie. Wskazuje prawidłowy bufor rozmiaru
s
bajtów._Outref_result_buffer_to_maybenull_(s, c)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null po stanie. Wskazuje bufor
s
elementów, z których pierwszac
jest prawidłowa._Outref_result_bytebuffer_to_maybenull_(s,c)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null w stanie post. Wskazuje bufor bajtów
s
, z których pierwszac
jest prawidłowa._Outref_result_buffer_all_maybenull_(s)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null w stanie post. Wskazuje prawidłowy bufor prawidłowego rozmiaru
s
elementów._Outref_result_bytebuffer_all_maybenull_(s)
Wynik musi być prawidłowy po stanie, ale może mieć wartość null w stanie post. Wskazuje prawidłowy bufor bajtów
s
prawidłowych elementów.
Wartości zwracane
Wartość zwracana funkcji przypomina _Out_
parametr, ale znajduje się na innym poziomie odwołania i nie musisz brać pod uwagę pojęcia wskaźnika do wyniku. W przypadku następujących adnotacji zwracana wartość jest obiektem z adnotacjami — skalarnym, wskaźnikiem do struktury lub wskaźnikiem do buforu. Te adnotacje mają te same semantyki co odpowiedni _Out_
adnotacja.
_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_
Parametry ciągu formatu
_Printf_format_string_
Wskazuje, że parametr jest ciągiem formatu używanym w wyrażeniuprintf
.Przykład
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_
Wskazuje, że parametr jest ciągiem formatu używanym w wyrażeniuscanf
.Przykład
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_
Wskazuje, że parametr jest ciągiem formatu używanym w wyrażeniuscanf_s
.Przykład
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; }
Inne typowe adnotacje
Adnotacje i opisy
_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)
Parametr, pole lub wynik znajduje się w zakresie (włącznie) z
low
dohi
._Satisfies_(_Curr_ >= low && _Curr_ <= hi)
Odpowiednik tej metody jest stosowany do obiektu z adnotacjami wraz z odpowiednimi warunkami wstępnymi lub po stanie.Ważne
Mimo że nazwy zawierają "in" i "out", semantyka i
_In_
_Out_
nie mają zastosowania do tych adnotacji._Pre_equal_to_(expr)
_Post_equal_to_(expr)
Wartość z adnotacjami jest dokładnie
expr
._Satisfies_(_Curr_ == expr)
Odpowiednik tej metody jest stosowany do obiektu z adnotacjami wraz z odpowiednimi warunkami wstępnymi lub po stanie._Struct_size_bytes_(size)
Dotyczy deklaracji struktury lub klasy. Wskazuje, że prawidłowy obiekt tego typu może być większy niż zadeklarowany typ, a liczba bajtów jest podana przez
size
. Na przykład:typedef _Struct_size_bytes_(nSize) struct MyStruct { size_t nSize; ... };
Rozmiar buforu w bajtach parametru
pM
typuMyStruct *
jest następnie przyjmowany jako:min(pM->nSize, sizeof(MyStruct))
Zobacz też
- Korzystanie z adnotacji SAL w celu zmniejszenia liczby defektów kodu C/C++
- Informacje o języku SAL
- Zachowanie funkcji dodawania adnotacji
- Dodawanie adnotacji do struktur i klas
- Dodawanie adnotacji do zachowania blokującego
- Określanie miejsca i warunków stosowania adnotacji
- Funkcje wewnętrzne
- Najlepsze rozwiązania i przykłady