Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #146644

Re: Indexing one past the end of array?

From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: Indexing one past the end of array?
Date 2019-10-06 08:05 -0700
Organization A noiseless patient Spider
Message-ID <867e5hap8d.fsf@linuxsc.com> (permalink)
References <gF6mF.2635984$c8w1.2556225@fx08.am4> <lnwodjvtkz.fsf@kst-u.example.com> <874l0moqit.fsf@bsb.me.uk> <5g9mF.47865$hL1.2883@fx35.iad>

Show all headers | View raw


Richard Damon <Richard@Damon-Family.org> writes:

> On 10/5/19 5:01 PM, Ben Bacarisse wrote:
>
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> 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.
>>
>> <cut>
>>
>>> 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.
>>
>> <cut>
>>
>>> 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.
>>
>>> (This is just an example.  The standard doesn't
>>> assume this kind of mapping between addresses and integer values.)
>>
>
> If pointers act like signed values, then the problem occurs at the
> midpoint (so sooner).

If pointers are taken as being signed, presumably the address space
starts at the most pointer value.  The whole space is still usable.

> Pointer differences are generally considered signed, and if pointer
> values are compared by this signed difference, then the issue only
> happens if a given array is over half the address space (which might
> well not be well supported).

The type of subtracting one pointer from another has been a signed
type (ptrdiff_t) since C90.  As you point out in the next paragraph
there is a problem only when the number of elements being spanned
is greater than PTRDIFF_MAX or less than PTRDIFF_MIN (or the
analogous values in C90).  This range may be larger than half the
address space, but is very likely not in most implementations.
However, when size_t is 16 bits, the whole address space will be
usable, as PTRDIFF_MAX must be at least 65535 (C99 onwards).

> If ptrdiff_t is the same size and size_t, than you get issues with
> arrays with more than SIZE_T_MAX/2 elements giving you overflow, but it
> is rare enough that I don't think many implementations make ptrdiff_t
> bigger than size_t to handle it.

The Standard gives an out here, by saying any difference of
pointers that gives a value not representable in type ptrdiff_t
gives undefined behavior.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Indexing one past the end of array? Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2019-10-06 04:02 +0800
  Re: Indexing one past the end of array? Keith Thompson <kst-u@mib.org> - 2019-10-05 13:13 -0700
    Re: Indexing one past the end of array? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-10-05 22:01 +0100
      Re: Indexing one past the end of array? Keith Thompson <kst-u@mib.org> - 2019-10-05 14:35 -0700
      Re: Indexing one past the end of array? Richard Damon <Richard@Damon-Family.org> - 2019-10-05 19:00 -0400
        Re: Indexing one past the end of array? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-06 08:05 -0700
      Re: Indexing one past the end of array? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-06 06:36 -0700
        Re: Indexing one past the end of array? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-10-06 16:31 +0100
    Re: Indexing one past the end of array? Richard Damon <Richard@Damon-Family.org> - 2019-10-05 17:10 -0400
      Re: Indexing one past the end of array? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-10-06 07:40 -0700
  Re: Indexing one past the end of array? Mateusz Viste <mateusz@wont.tell> - 2019-10-05 20:26 +0000
  Re: Indexing one past the end of array? chad <cdalten@gmail.com> - 2019-10-05 16:55 -0700
  Re: Indexing one past the end of array? "Oliver S." <Follow.Me@gmx.net> - 2019-10-06 15:50 +0200
  Re: Indexing one past the end of array? "Oliver S." <Follow.Me@gmx.net> - 2019-10-06 17:04 +0200
    Re: Indexing one past the end of array? scott@slp53.sl.home (Scott Lurndal) - 2019-10-07 13:32 +0000
      Re: Indexing one past the end of array? "Oliver S." <Follow.Me@gmx.net> - 2019-10-07 17:23 +0200

csiph-web