Advertisement

Standard C's pointer difference type

October 18, 2007

Dan_Saks-October 18, 2007

Though not as useful and prevalent as size_t, ptrdiff_t is still worth a look.

I recently wrote a couple of columns in which I explained why the Standard C and C++ libraries define a typedef named size_t. The type size_t is an alias for whichever unsigned integer type is the result of the sizeof operator. It corresponds to the smallest unsigned integer type capable of representing the size of the largest possible object in the target environment. Depending on the target, size_t might be an alias for unsigned, for unsigned long, or for unsigned long long.

In response to those columns, a few readers suggested that ssize_t is a useful alternative to size_t. Some C libraries define ssize_t as a signed integer type that has the same size as size_t. Inasmuch as ssize_t isn't part of Standard C (or Standard C++), I don't recommend using it unless you need it to communicate with a library that provides its own ssize_t. Instead, I recommend using ptrdiff_t.

Standard C provides the odd-sounding typedef ptrdiff_t (pronounced PUT-er-diff-TEE) as the signed counterpart to size_t. Although the standard offers no explicit guarantee that sizeof(ptrdiff_t) equals sizeof(size_t), I have yet to use a compiler for which this isn't so.

In truth, the C standard doesn't define ptrdiff_t as having any direct relationship to size_t. Rather, it defines ptrdiff_t as the signed integer type of the result of subtracting two pointers. For example, given:

T *p, *q;

for any non-void type T, you can write expressions such as:

d = p - q;

If you declare d as:

ptrdiff_t d;

then the assignment above should behave properly when compiled with any Standard C compiler. If you were to declare d as some other integer type, such as:

int d;

then the assignment might provoke a warning from the compiler, or worse, silently truncate the assigned value at run time.

Whereas numerous functions of the Standard C library have parameters or return values of type size_t, none has parameters or return values of type ptrdiff_t. In contrast, the Standard C++ library uses ptrdiff_t, though not as often as it uses size_t. Most of those uses appear in the generic iterator components of the standard library.

You can use printf to display a ptrdiff_t. According to the 1999 C Standard, the format string should contain the t length modifier with the d or i conversion specifier, as in:

ptrdiff_t d;
...
printf("%td", d);

Although the d specifier has been around as long as C, the t modifier is fairly new. Few C libraries support it yet.

If your compiler doesn't support %td, then you should try %ld, as in:

printf("%ld", (long)d);

Displaying a ptrdiff_t using the Standard C++ iostream library is a simple as displaying any other numeric type:

std::cout << d;

Dan Saks is president of Saks & Associates, a C/C++ training and consulting company. For more information about Dan Saks, visit his website at www.dansaks.com. Dan also welcomes your feedback: e-mail him at dsaks@wittenberg.edu. For more information about Dan click here .

1. Saks, Dan. "Why size_t matters," Embedded Systems Design, July 2007, p. 11.

2. Saks, Dan. "Further insights into size_t," Embedded Systems Design, September 2007, p. 9.

Loading comments...