If I allocated something like
size_t n = ???;
unsigned char* s = malloc(n);
will it be perfectly defined behaviour to compare pointers to locations s + i for 0 <= i < n in the sense that s + i < s + j if and only if i < j? Probably it is, but one reads that pointer comparison is defined only in a contagious array, and to a beginner it is not clear if an allocated thing as above would count as an "array" since that term has also a formal meaning in C, and also one reads about virtual memory without fully yet digesting that, and starts to worry... So I thought to ask to make sure.
The C standard has its problem here. Because what's returned from malloc is just a chunk of memory with no declared type. In theory it is not an array or any other type (yet). In practice the compiler must treat it like an array or otherwise the whole C language falls apart. Nobody thought of this when the C99 standard was designed and ISO C working groups since then have shied away from fixing the problem.
To tell if something is a valid access, we need to know its type, or if there is no declared type like in the
malloccase, then at least we need to know the effective type, which is a system that the C standard launched with C99 to address such scenarios.Formally,
spoints at memory location having no declared type. C17 6.5 §6 then says:But you don't access it, so it has no effective type either. And since it has neither a declared nor an effective type, it cannot be an array of some type either. Doing pointer arithmetic on
swhich is not an array, is undefined behavior per C17 6.5.6 §8. Unless you access it first and thereby mark it as some sort of effective type.Obviously we can't read the C standard literally here - it is broken. Specifically, it has the following defects:
In order to produce some sort of meaningful executable, compilers therefore ignore all of this and treat whatever is returned by
mallocas an array. Similarly, compilers tend to support pointer arithmetic on areas with no declared type just fine, or hardware-related programming in C would also be impossible.So to summarize:
Will it be perfectly defined behavior to do pointer arithmetic within this allocated chunk?
No.
Can you compare two pointers pointing into the chunk?
Yes, you can always compare two pointers in C no matter where they point. But how will you get the pointers pointing into this chunk with no type, without using pointer arithmetic?
Will it work just fine on every half-decent compiler ever released?
Yes.