Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Indexing one past the end of array?
Date: Sun, 06 Oct 2019 06:36:04 -0700
Organization: A noiseless patient Spider
Lines: 58
Message-ID: <86ftk69et7.fsf@linuxsc.com>
References: <874l0moqit.fsf@bsb.me.uk>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="a0bfc71282e15a9952a47d73886d6801"; logging-data="16009"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18qD33WUXwMxYdh7H6raVNA8tyQ8c0xTUU="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:WrHakH3/jy5YwU8fsy3gD2WoNBI= sha1:rU/feX9pkBYhgYdSea4sErO2OPA=
Xref: csiph.com comp.lang.c:146638
Ben Bacarisse writes:
> Keith Thompson writes:
>
>> Johann 'Myrkraverk' Oskarsson writes:
>>
>>> Dear comp.lang.c,
>>>
>>> I've been reading a thread on LWN[1], notably this quote:
>>>
>>>> Just some pedantry, but I believe you're allowed to point to the first
>>>> element after the end of an array, as long as you don't dereference
>>>> that element. Pointer comparisons with such a pointer are supposed to
>>>> work, too.
>>>
>>> Elsewhere, I've read that on embedded systems memory can be allocated
>>> right up to the end of memory, and therefore such indexes are invalid
>>> (but I cannot remember where).
>>>
>>> So, is it always legal to calculate one past the end of an array or
>>> allocated memory?
>>>
>>> [1] https://lwn.net/Articles/278137/
>>
>> Yes, it's always legal. The language guarantees it.
>
>
>
>> A compiler needs to do whatever it has to to make this work as
>> specified. Allocating an object at the very end of memory doesn't
>> necessarily break this, as long as pointer addition and subtraction
>> yield the expected results.
>
>
>
>> For example, assume a system with 32-bit addresses and exactly 2**32
>> bytes of addressable memory. Assume an array object
>> char buf[100];
>> is allocated starting at address 2**32-100. Then (buf+100) points just
>> past the end of the array, and also just past the end of addressable
>> memory. As long as evaluating (buf+100)-1 yields a valid pointer to
>> buf[99], that's ok.
>
> A nit: the relational operators (<, >, <=, >=) have to work on the
> resulting pointers as well. For example (buf+100)-1 < (buf+100) must be
> true, and that's not automatically the case where pointers are
> interpreted as unsigned bit patterns. If, however, pointers are signed
> 2's complement values, it will all come out in the wash.
It took me a while to figure out what you meant by the statement
about signed pointers. What I think you mean is that if the
signed address of 'buf' is -100, then the comparisons (and
arithmetic) all work as required. But if pointers are signed
there is still a singularity; it just occurs at a different point
in the address space. A 100-byte array starting at 2**31-100
will still have the problem: a pointer past the last element of
the array will be less than -- instead of greater than -- a
pointer to any element of the array.