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

做~自己de王妃 提交于 2019-11-30 23:10:52
Pascal Cuoq

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.

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.

jwdonahue

The answer to the OP's question is yes, size_t is most appropriate for the example code, where no pointer values are being subtracted from each other, and there are no cross-compiler/library compatibility issues around malloc behaviors. Regardless of difference in heap managers, in C, an array can be SIZE_MAX bytes in length and that requires a size_t to represent it. Nothing in the standard requires a heap manager to be able to allocate all of a process memory space in the heap, or to allocate up to SIZE_MAX bytes for that matter, but an array can be SIZE_MAX in length, hence size_t is appropriate.

Even if n is signed, using a ptrdiff_t for i isn't going to help, as the initial i < n test will fail anyway, if n is negative, because i is initialized to zero. There is no index into i that a size_t index cannot access. The only place that ptrdiff_t is needed, is where you subtract one pointer value from another, and the OP isn't asking about that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!