CS 3358 (Data Structures and Algorithms) by Lee S. Koh
About size_t and its pitfalls

What is size_t? (When to use it and the pitfalls to watch out for when using it.)

As the name is meant to suggest (had they followed my style guide, it'd probably be size_type and not size_t), size_t represents the most suitable type that one can use to declare variables/constants for sizing and counting things when coding in C/C++. The most suitable type is one that will use the minimum amount of memory (maximum efficiency) and still be able to accommodate the entire range of values that is likely to be encountered (maximum desired flexibility). For sizing and counting, only nonnegative values are involved. Therefore the most suitable C/C++ built-in type for the purpose is either unsigned int or unsigned long int. The question is which of the two should we use. Since an unsigned long int uses at least the same amount of memory as an unsigned int, but likely more, we would want to use it only if we really need it (for maximum efficiency). Whether we really need it or not is in turn determined by the range of values that is likely to be encountered (the maximum desired flexibility), which unfortunately is platform dependent. It would be a lot of pain for the programmer to have to figure out which of the two (unsigned int or unsigned long int) is most suitable for a particular platform, and to have to figure it out again (and incorporate any necessary adjustments) each time there is a need to port a program from one platform to another. To relieve programmers of this burden, the compiler writers agreed to follow an established rule, which is for them (the compiler writers) to figure out whether it is unsigned int or unsigned long int that is the most suitable size type for a particular platform that they are writing the compiler for. They will then define a symbolic type name called size_t in the cstdlib header file to be this most suitable size type. This way, and provided that the cstdlib header file is included, programmers can simply use size_t to represent the most suitable size type when they need it for sizing and counting pusposes in their code, without having to worry about the issue of platform dependence.

PITFALL: Because size_t is an unsigned type (recall that it is either unsigned int or unsigned long int), we must be careful not to use a variable of type size_t in such a way that the variable is required to store a value below zero. This may at first seem like a trivial one that is not worth noting, but believe me many past students fell into it and wasted many frustrating hours trying to figure out what went wrong. To help you appreciate this, let's consider a rather simple program that is to count down and display values from START_VALUE to 0, where START_VALUE is some nonzero positive number. Try compiling and running the following program:

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
   const size_t START_VALUE = 10;
   size_t i;

   for (i = START_VALUE; i >= 0; i--)
      cout << i << endl;

   return EXIT_SUCCESS;
}

Does the program work as intended? If not, can you see why? Do you know how to correct it (click here for answer)?

PITFALL: Another size_t related pitfall occurs only on some strict compilers. It is illustrated by the following example:

#include <iostream>
#include <cstdlib>
using namespace std;

template <class T>
void EchoManyTimes(T value, size_t numOfTimes);

int main()
{
   const int J = 3;
   const size_t K = 4;

   int    i = 2;
   double d = 3.3;
   char   c = 'a';

   EchoManyTimes(1, 1);
   EchoManyTimes(i, i);
   EchoManyTimes(d, J);
   EchoManyTimes(c, K);

   return EXIT_SUCCESS;
}

template <class T>
void EchoManyTimes(T value, size_t numOfTimes)
{
   size_t count;

   for (count = 1; count <= numOfTimes; count++)
      cout << value << endl;
}

This program fails on strict compilers because such compilers require that the arguments of a template function have an exact match, with no type conversion. Click here to see how this problem can be overcome/avoided.