Anotando estruturas e classes
Você pode anotar structs e membros de classe usando anotações que agem como invariáveis, presume-se que elas sejam verdadeiras em qualquer chamada de função ou entrada/saída de função que envolva a estrutura delimitante como um parâmetro ou um valor de resultado.
Anotações de classe e struct
_Field_range_(low, high)
O campo está no intervalo (inclusivo) de
low
atéhigh
. Equivalente à_Satisfies_(_Curr_ >= low && _Curr_ <= high)
aplicada ao objeto anotado usando as pré ou pós condições apropriadas._Field_size_(size)
,_Field_size_opt_(size)
,_Field_size_bytes_(size)
,_Field_size_bytes_opt_(size)
Um campo que tem um tamanho gravável em elementos (ou bytes), conforme especificado por
size
._Field_size_part_(size, count)
,_Field_size_part_opt_(size, count)
,_Field_size_bytes_part_(size, count)
,_Field_size_bytes_part_opt_(size, count)
Um campo que tem um tamanho gravável em elementos (ou bytes), conforme especificado por
size
, e acount
desses elementos (bytes) que são legíveis._Field_size_full_(size)
,_Field_size_full_opt_(size)
,_Field_size_bytes_full_(size)
,_Field_size_bytes_full_opt_(size)
Um campo que tem um tamanho legível e gravável em elementos (ou bytes), conforme especificado por
size
._Field_z_
Um campo que tem uma cadeia de caracteres terminada em nulo.
_Struct_size_bytes_(size)
Aplica-se à 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 especificado 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 tipoMyStruct *
é então usado para ser:min(pM->nSize, sizeof(MyStruct))
Exemplo
#include <sal.h>
// This _Struct_size_bytes_ is equivalent to what below _Field_size_ means.
_Struct_size_bytes_(__builtin_offsetof(MyBuffer, buffer) + bufferSize * sizeof(int))
struct MyBuffer
{
static int MaxBufferSize;
_Field_z_
const char* name;
int firstField;
// ... other fields
_Field_range_(1, MaxBufferSize)
int bufferSize;
_Field_size_(bufferSize) // Preferred way - easier to read and maintain.
int buffer[]; // Using C99 Flexible array member
};
Anotações para este exemplo:
_Field_z_
é equivalente a_Null_terminated_
._Field_z_
para o campo de nome, especifica que o campo de nome é uma cadeia de caracteres terminada em nulo._Field_range_
parabufferSize
especifica que o valor debufferSize
deve estar entre 1 eMaxBufferSize
(ambos inclusivos).- Os resultados finais das anotações
_Struct_size_bytes_
e_Field_size_
são equivalentes. Para estruturas ou classes que têm um layout semelhante,_Field_size_
é mais fácil de ler e manter, pois tem menos referências e cálculos do que a anotação equivalente_Struct_size_bytes_
._Field_size_
não requer conversão para o tamanho do byte. Se o tamanho do byte for a única opção, por exemplo, em um campo de ponteiro vazio,_Field_size_bytes_
poderá ser usado. Se_Struct_size_bytes_
e_Field_size_
existirem, ambos ficarão disponíveis para ferramentas. Caberá à ferramenta decidir o que fazer se as duas anotações discordarem.
Confira também
- Usando anotações de SAL para reduzir defeitos de código do C/C++
- Noções básicas de SAL
- Anotando parâmetros de função e valores de retorno
- Anotando o comportamento da função
- Anotando o comportamento de bloqueio
- Especificando quando e onde uma anotação se aplica
- Funções intrínsecas
- Práticas recomendadas e exemplos