Can I assume the following invariant?
void foo(char *buf, size_t len) {
// "buf" points to either an array or memory allocated with malloc().
assert((uintptr_t)(buf + len) < UINTPTR_MAX);
}
In a parser I am writing I want to mark certain offsets using pointers: for example I might have char *end_of_submessage, where end_of_submessage is relative to my current buffer. But if the submessage does not end inside the current buffer, I want to use a value that is larger than any offset in the current buffer could possibly be. So I would do:
void parse(char *buf, size_t len, uintptr_t end_of_submessage) {
// Some parsing that might increment "buf"
// ...
// If end_of_submessage == UINTPTR_MAX, processing will not be
// triggered even if we have processed our entire current buffer.
if ((uintptr_t)buf >= end_of_submessage)
process_submsg_end();
}
But this scheme would be thwarted if malloc() returned memory such that ptr + len == UINTPTR_MAX, or an array had the same property. Is it safe to assume this will never happen? Is it safe according to the standard? If not, is it safe in practice?
The only guarantee that the C standard provides is follows:
No guarantees are given about the precise content of these converted integers. In particular, given a char pointer
p,(uintptr_t)(p + 1) == ((uintptr_t)p) + 1is not guaranteed to be true.If you want to mark offsets, you should use a
ptrdiff_toffset from another pointer, or you can simply use a pointer to mark the end. For example:If
end_of_submessagemay lie in a different buffer, you can use something like: