What is size_t in C?
I am getting confused with size_t
in C. I know that it is returned by the sizeof
operator. But what exactly is it? Is it a data type?
Let's say I have a for
loop:
for(i = 0; i < some_size; i++)
Should I use int i;
or size_t i;
?
Solution 1:
From Wikipedia:
According to the 1999 ISO C standard (C99),
size_t
is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).
size_t
is an unsigned data type defined by several C/C++ standards, e.g. the C99 ISO/IEC 9899 standard, that is defined instddef.h
.1 It can be further imported by inclusion ofstdlib.h
as this file internally sub includesstddef.h
.This type is used to represent the size of an object. Library functions that take or return sizes expect them to be of type or have the return type of
size_t
. Further, the most frequently used compiler-based operator sizeof should evaluate to a constant value that is compatible withsize_t
.
As an implication, size_t
is a type guaranteed to hold any array index.
Solution 2:
size_t
is an unsigned type. So, it cannot represent any negative values(<0). You use it when you are counting something, and are sure that it cannot be negative. For example, strlen()
returns a size_t
because the length of a string has to be at least 0.
In your example, if your loop index is going to be always greater than 0, it might make sense to use size_t
, or any other unsigned data type.
When you use a size_t
object, you have to make sure that in all the contexts it is used, including arithmetic, you want non-negative values. For example, let's say you have:
size_t s1 = strlen(str1);
size_t s2 = strlen(str2);
and you want to find the difference of the lengths of str2
and str1
. You cannot do:
int diff = s2 - s1; /* bad */
This is because the value assigned to diff
is always going to be a positive number, even when s2 < s1
, because the calculation is done with unsigned types. In this case, depending upon what your use case is, you might be better off using int
(or long long
) for s1
and s2
.
There are some functions in C/POSIX that could/should use size_t
, but don't because of historical reasons. For example, the second parameter to fgets
should ideally be size_t
, but is int
.
Solution 3:
size_t
is a type that can hold any array index.
Depending on the implementation, it can be any of:
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
Here's how size_t
is defined in stddef.h
of my machine:
typedef unsigned long size_t;
Solution 4:
If you are the empirical type,
echo | gcc -E -xc -include 'stddef.h' - | grep size_t
Output for Ubuntu 14.04 64-bit GCC 4.8:
typedef long unsigned int size_t;
Note that stddef.h
is provided by GCC and not glibc under src/gcc/ginclude/stddef.h
in GCC 4.2.
Interesting C99 appearances
-
malloc
takessize_t
as an argument, so it determines the maximum size that may be allocated.And since it is also returned by
sizeof
, I think it limits the maximum size of any array.See also: What is the maximum size of an array in C?
Solution 5:
The manpage for types.h says:
size_t shall be an unsigned integer type