Estou ficando confuso com o size_t
em C. Eu sei que ele é devolvido pelo operador sizeof
. Mas o que exatamente é isso? É um tipo de dado?
Digamos que eu tenho um loop "para":
for(i = 0; i < some_size; i++)
Devo utilizar int i;
ou size_t i;
?
De acordo com a norma ISO C de 1999 (C99),
size_t
é um número inteiro não assinado tipo de pelo menos 16 bit (ver secções 7.17 e 7.18.3).
size_t
é um tipo de dado não assinado definido por vários padrões C/C++, por exemplo, a norma C99 ISO/IEC 9899, isso é definido emstddef.h
.1 Ele pode ser ainda mais importado através da inclusão destdlib.h
como este arquivo internamente sub incluistddef.h
.Este tipo é utilizado para representar o tamanho de um objecto. Funções da biblioteca que tomam ou retornam tamanhos os esperam para ser do tipo ou ter o tipo de retorno de 'tamanho_t'. Além disso, o mais frequentemente usado com base em compiladores o tamanho do operador deve ser avaliado a um valor constante que é compatível com
size_t
.
Como uma implicação, o size_t
é um tipo garantido para manter qualquer índice de array.
O size_t
é um tipo não assinado. Portanto, ele não pode representar nenhum valor negativo(<0). Você o utiliza quando está contando algo, e tem certeza de que não pode ser negativo. Por exemplo, strlen()
retorna um size_t
porque o comprimento de uma string tem que ser pelo menos 0.
No seu exemplo, se o seu índice de loop vai ser sempre maior que 0, pode fazer sentido utilizar size_t
, ou qualquer outro tipo de dado não assinado.
Quando você utiliza um objeto size_t
, você tem que ter certeza que em todos os contextos ele é utilizado, incluindo aritmética, você quer valores não-negativos. Por exemplo, deixe's dizer que você tem:
size_t s1 = strlen(str1);
size_t s2 = strlen(str2);
e você quer encontrar a diferença entre os comprimentos de str2
e str1
. Você não pode fazer:
int diff = s2 - s1; /* bad */
Isto porque o valor atribuído a diff
será sempre um número positivo, mesmo quando s2 < s1
, porque o cálculo é feito com tipos não assinados. Neste caso, dependendo de qual é o seu caso de uso, você pode estar melhor usando int
(ou long long
) para s1
e s2
.
Existem algumas funções no C/POSIX que poderiam/deveriam utilizar size_t
, mas don't devido a razões históricas. Por exemplo, o segundo parâmetro para "esquece" deveria idealmente ser size_t
, mas é int
.