Posts Tagged ‘portability’

Correct Use of size_t

Saturday, January 31st, 2009

One misunderstood part of C is size_t. First appearing in ANSI C around 1990, size_t is routinely misused. People either use size_t incorrectly or they don’t don’t use it at all. The idea of its use is simple and I’ll attempt an equally simple explanation. The appropriate use for size_t is to describe the size of objects and not as an alias for unsigned int.

unsigned long min_index=min, max_index=max;
for (size_t i=min_index; i++) data_array[i]++;

The previous code can break. The assumption in the previous code sample is that size_t can store min_index and max_index, but on some platforms, size_t may be smaller than an unsigned long, causing overflow errors. The above code should use unsigned long for the index.

Using size_t as an alias for some type of int on your target architectures may seem functionally sound, but your assumptions are likely wrong and the code is semantically wrong. Since the type of size_t will shift from platform to platform, you shouldn’t rely on size_t to do anything other than describe the size of objects and types.

int obj_size = get_obj_size();
struct very_large_struct *ptr_src_vl=src, *ptr_dest_vl=dest;
ptr_src_vl = malloc(obj_size);
/* sanity checking for ptr_src_vl validity not shown */
memcpy(ptr_src_vl, ptr_dest_vl, obj_size);

The previous code is not using size_t where it should. The C standard states int types must be at least 16 bits. Therefore, the above code has an implicit limit through the size of the int type. Imagine size_t is 16-bits and has a sign (it can happen, but shouldn’t) yielding a maximum value of 32,767. The lesson is: the maximum value for an int type has no bearing on the maximum object size for a platform. However,  size_t will hold the maximum possible object size for your system (assuming your C implementation is correct). If you go with the C standard on this issue, it will help your code portability and maintainability.