Question

By reading on the posts online related to size_t and ptrdiff_t, I want to confirm the following:

  1. if the max size of an array is less than 1/2*(max number represent-able by size_t), I can safely use ptrdiff_t and check the relative distances between two pointers to the same object?(Since I was talking about array, "pointers to same object" means "pointers to same array").

  2. if I want to declare a variable that can represent the offset from another pointer, I better declare it as type ptrdiff_t ?

  3. How do I output variables of type size_t and ptrdiff_t in C and C++? Is the following correct: Cross platform format string for variables of type size_t?

  4. is uintptr_t is just another name for size_t OR it should be used as a separate type from size_t?

  5. is ssize_t and intptr_t another names for ptrdiff_t OR it has to be used differently?

I am starting to use gcc on Ubuntu. I just found out about these types when using someone else's codes.

ADDed: I do want to be able to use negative offsets. And any difference in using uintptr_t and intptr_t?

Was it helpful?

Solution

1: if the max size of an array is less than 1/2*(max number represent-able by size_t), I can safely use ptrdiff_t and check the relative distances between two pointers to the same object?

That will be the case if sizeof(size_t) <= sizeof(prtdiff_t). That will be the case in a sensible implementation, but there is no guarantee.

2: if I want to declare a variable that can represent the offset from another pointer, I better declare it as type ptrdiff_t ?

Yes, that is what the type is intended for.

3: How do I output variables of type size_t and ptrdiff_t in C and C++?

In C:

printf("%zu %td\n", size, ptrdiff);

In C++:

std::cout << size << ' ' << ptrdiff << '\n';

4: is uintptr_t is just another name for size_t OR it should be used as a separate type from size_t?

It should be regarded as a separate type. uintptr_t is an integer type that can contain any pointer value converted to an integer; it may not exist on some platforms.

5: is ssize_t and intptr_t anther name for ptrdiff_t OR it has to be used differently?

ssize_t is not a standard type as far as the C or C++ languages are concerned; it is defined by Posix as the type of some function arguments and return values. It would be best to use ptrdiff_t except when dealing directly with Posix functions.

intptr_t is intended for holding an integer representation of a pointer, not a difference between pointers. On some platforms, these may have different sizes, and intptr_t may not be defined at all, so they should not be used interchangeably.

I do want to be able to use negative offsets. And any difference in using uintptr_t and intptr_t?

Don't use either of these types to represent offsets; use ptrdiff_t. Use these types in special circumstances, when you want to convert pointers to their integer representations for some reason.

OTHER TIPS

uintptr_t and intptr_t are big enough to hold any void* pointer value without loss of information. They need to be able to uniquely represent the address of any object in your program's entire address space -- including any byte within any object.

size_t is the type yielded by the sizeof operator; ptrdiff_t is the type yielded by subtracting two pointers. They only need to be big enough for a single object. (And it's possible to have an object so big that subtracting two pointers that point to opposite ends will overflow.)

Most current systems have a single monolithic address space, but C is designed to work on systems that don't. For example, on some systems the largest possible object might be a small fraction of the size of the entire address space -- and comparing or subtracting pointers to distinct objects, might be meaningless. (Think about a segmented addressing scheme, where pointer subtraction and comparison consider only the offset portion of the address.)

Assuming _ptrdiff_t_ is a typo:

1) Yes. If the max size of an array is less than SIZE_MAX/2, You can safely use ptrdiff_t
2) Sometimes: ptrdiff_t is usually the differences between two pointers, while size_t is an offset. The important thing here is size_t is always positive, ptrdiff_t might be negative. Note that on some platforms, they may be vastly different sizes.
3) You output variables of type size_t and ptrdiff_t the same way you output any other variable type.

size_t a = 10;
ptrdiff_t b = 20;
printf("%u %d", ((unsigned int)a), ((int)b));
std::cout << a << b;

4) uintptr_t is an unsigned integer at least as big as an int*, to safely allow integer math on pointers. size_t is not guaranteed to be the same as far as I can tell.
5) ssize_t is a nonstandard C type, corresponding to ptrdiff_t. Use ptrdiff_t instead. (On platforms supporting the POSIX 1003.1-1996 API standard, which includes most Unix-like systems, a signed variant of size_t named ssize_t is available, which was not part of the ANSI or ISO C standards. http://en.wikipedia.org/wiki/Size_t)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top