Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For iterating though an array should we be using size_t or ptrdiff_t?

In this blog entry by Andrey Karpov entitled, "About size_t and ptrdiff_t" he shows an example,

for (ptrdiff_t i = 0; i < n; i++)
  a[i] = 0;

However, I'm not sure if that's right, it seems that should be

for (size_t i = 0; i < n; i++)
  a[i] = 0;

Is this correct?

I know we should also likely be using something like memset, but let's avoid that entirely. I'm only asking about the type

like image 987
NO WAR WITH RUSSIA Avatar asked Aug 30 '25 17:08

NO WAR WITH RUSSIA


2 Answers

In a blog post, I argue that you should always refrain from allocating memory blocks larger than PTRDIFF_MAX(*), because doing so will make compilers such as Clang and GCC generate nonsensical code even if you do not subtract pointers to that block in a way that causes the result to overflow.

(*) Even if malloc succeeds when you pass it a value larger than PTRDIFF_MAX. The crux of the problem is that GCC and Clang only generate code that behaves correctly when linked with such a malloc, but Glibc provides a malloc function that does not implement this limitation.

If you follow that constraint (which I encourage you to: that's the message of the blog post), then both types are equally correct.

This said, since only positive offsets need to be represented, size_t would be the natural choice in your example.

like image 130
Pascal Cuoq Avatar answered Sep 02 '25 07:09

Pascal Cuoq


Use of ptrdiff_t is ok since a[i] is translated as *(a + i).

If you take two pointers, p1 and p2, it is encouraged that you use:

ptrdiff_t d = p2 - p1; // Assuming p2 - p1 is valid.

Given that, p2 == p1 + d, i.e. <ptr type> + ptrdiff_t is a valid expression. Whether ptrdiff_t or size_t is better as the index type is a matter of opinion and/or coding style used in a team.

like image 22
R Sahu Avatar answered Sep 02 '25 07:09

R Sahu