'Object size from (begin, end) pointers in strictly conforming C
Suppose I have two pointers to char pointing to the beginning, begin, and just past the end, end, of an array of some kind (as is customary in C++ before ranges, for example). One would expect all I would need to do to calculate the size of said array in bytes would be to compute end − begin.
However, the latest ISO C standard has the following to say about it (in §6.5.6 paragraph 9, emphasis mine):
When two pointers are subtracted [...] the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is
ptrdiff_tdefined in the<stddef.h>header. If the result is not representable in an object of that type, the behavior is undefined.
Equivalent phrasing is present all the way back to ANSI C §6.3.6.
This seems to be a problem, and not an entirely theoretical one, both on systems with 16-bit size_t and ptrdiff_t where one would want to handle arrays of size ≥ 215, and on systems with 32-bit size_t and ptrdiff_t where one does occasinonally want to handle arrays of size ≥ 231 (e.g. on a 32-bit Windows server running with /3GB).
(The first case has been made non-conforming by C99 requiring ptrdiff_t to hold values up to at least 216 − 1, but that requirement has been widely ignored on embedded systems. The second is somewhat complicated by GCC and Clang in their default configurations silently miscompiling 32-bit code that links to malloc succeeding with ≥ 231 bytes. But I’d argue that both are still reasonable things to want to do.)
In fact, the inability to calculate the size of an object from a (begin, end) pair by subtracting was given by the current editor of the ISO C standard to avoid adding an API that takes such pairs. (Such APIs are in any case unusual for the C standard library, though, unlike in C++.)
So, is there an O(1) way to calculate the size of an arbitrarily-sized object given (begin, end) pointers in a strictly conforming ISO C program? You could always do size_t size = 0; while (begin++ < end) size++; as an O(size) solution, of course, but that seems silly even if a modern optimizing compiler can figure it out.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
