Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.fortran > #73508 > unrolled thread
| Started by | Lynn McGuire <lynnmcguire5@gmail.com> |
|---|---|
| First post | 2022-08-26 15:49 -0500 |
| Last post | 2022-08-29 22:59 -0700 |
| Articles | 20 on this page of 60 — 20 participants |
Back to article view | Back to comp.lang.fortran
“Why do arrays start at 0?" Lynn McGuire <lynnmcguire5@gmail.com> - 2022-08-26 15:49 -0500
Re: “Why do arrays start at 0?" Gary Scott <garylscott@sbcglobal.net> - 2022-08-26 16:56 -0500
Re: “Why do arrays start at 0?" Mr Flibble <flibble@reddwarf.jmc.corp> - 2022-08-27 00:46 +0100
Re: “Why do arrays start at 0?" d thiebaud <thiebauddick2@aol.com> - 2022-08-26 22:29 -0400
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-26 19:34 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-26 20:34 -0700
Re: “Why do arrays start at 0?" Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-08-26 22:05 -0700
Re: “Why do arrays start at 0?" Mr Flibble <flibble@reddwarf.jmc.corp> - 2022-08-27 12:06 +0100
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-26 18:24 -0700
Re: Re: “Why do arrays start at 0?" scott@slp53.sl.home (Scott Lurndal) - 2022-08-27 14:28 +0000
Re: �Why do arrays start at 0?" Charlie Roberts <croberts@gmail.com> - 2022-08-28 10:25 -0400
Re: “Why do arrays start at 0?" Louis Krupp <lkrupp@invalid.pssw.com.invalid> - 2022-08-26 16:08 -0600
Re: �Why do arrays start at 0?" Charlie Roberts <croberts@gmail.com> - 2022-08-28 10:28 -0400
Re: Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-28 16:30 +0000
Re: “Why do arrays start at 0?" Ron Shepard <nospam@nowhere.org> - 2022-08-29 02:42 -0500
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-30 17:18 +0000
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-30 12:15 -0700
Re: “Why do arrays start at 0?" Mr Flibble <flibble@reddwarf.jmc.corp> - 2022-08-27 00:44 +0100
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-26 20:31 -0700
Re: “Why do arrays start at 0?" "fiz...@gmail.com" <fiziqs@gmail.com> - 2022-08-27 01:48 -0700
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-27 02:17 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-27 09:30 +0000
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-27 10:01 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-27 22:13 +0000
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-27 22:26 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-28 06:59 +0000
Re: “Why do arrays start at 0?" Lynn McGuire <lynnmcguire5@gmail.com> - 2022-08-28 13:42 -0500
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-28 20:17 +0000
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-28 14:08 -0700
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-28 14:05 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-28 21:54 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-28 21:53 -0700
Re: “Why do arrays start at 0?" Ron Shepard <nospam@nowhere.org> - 2022-08-29 02:07 -0500
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-29 01:30 -0700
Re: “Why do arrays start at 0?" Ron Shepard <nospam@nowhere.org> - 2022-08-29 10:13 -0500
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-29 12:30 -0700
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-29 03:48 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-27 05:16 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-27 05:47 +0000
Re: “Why do arrays start at 0?" d thiebaud <thiebauddick2@aol.com> - 2022-08-27 15:19 -0400
Re: “Why do arrays start at 0?" FortranFan <parekhvs@gmail.com> - 2022-08-27 12:45 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-27 22:22 +0000
Re: “Why do arrays start at 0?" "Fred. Zwarts" <F.Zwarts@KVI.nl> - 2022-08-27 21:26 +0200
Re: “Why do arrays start at 0?" Lynn McGuire <lynnmcguire5@gmail.com> - 2022-08-27 15:01 -0500
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-27 22:24 +0000
Re: “Why do arrays start at 0?" John <urbanjost@comcast.net> - 2022-08-27 19:34 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-28 01:50 -0700
Re: “Why do arrays start at 0?" Lynn McGuire <lynnmcguire5@gmail.com> - 2022-08-27 22:40 -0500
Re: “Why do arrays start at 0?" Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-08-27 22:07 -0700
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-27 23:04 -0700
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-28 07:50 +0000
Re: “Why do arrays start at 0?" David Brown <david.brown@hesbynett.no> - 2022-08-28 11:52 +0200
Re: “Why do arrays start at 0?" Paavo Helde <eesnimi@osa.pri.ee> - 2022-08-28 19:43 +0300
Re: “Why do arrays start at 0?" "Fred. Zwarts" <F.Zwarts@KVI.nl> - 2022-08-28 10:01 +0200
Re: “Why do arrays start at 0?" Thomas Koenig <tkoenig@netcologne.de> - 2022-08-28 08:14 +0000
Re: “Why do arrays start at 0?" Bonita Montero <Bonita.Montero@gmail.com> - 2022-08-28 11:07 +0200
Re: “Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-28 02:55 -0700
Re: “Why do arrays start at 0?" Robin Vowels <robin.vowels@gmail.com> - 2022-08-28 05:47 -0700
Re: ???Why do arrays start at 0?" Juha Nieminen <nospam@thanks.invalid> - 2022-08-29 11:15 +0000
Re: ???Why do arrays start at 0?" gah4 <gah4@u.washington.edu> - 2022-08-29 22:59 -0700
Page 3 of 3 — ← Prev page 1 2 [3]
| From | FortranFan <parekhvs@gmail.com> |
|---|---|
| Date | 2022-08-27 12:45 -0700 |
| Message-ID | <3a510e33-5963-48b4-afe8-ffeb27aa5ad3n@googlegroups.com> |
| In reply to | #73527 |
On Saturday, August 27, 2022 at 3:19:26 PM UTC-4, d thiebaud wrote:
> On 8/27/22 01:47, Thomas Koenig wrote:
> > Lynn McGuire schrieb:
> >> “Why do arrays start at 0?"
> >> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/
> >>
> >> "It's not the reason you think. No, it's not that reason either.”
> >>
> >> My Fortran starts at one. My C++ starts at zero. This has made my life
> >> hell.
> >
> > If you want to declare your Fortran arrays to start at zero, just
> > declare them with a lower bound of zero, like
> >
> > real, dimension(0:n-1) :: a
> Can you declare other lower bounds the same way?
Re: "Can you declare other lower bounds the same way?", yes.
Below is a simple example with the so-called assume-shape array parameters where array descriptors come into play during procedure invocation:
real :: x(2,3,4)
x = reshape( [( i, integer :: i = 1, size(x) )], shape=shape(x) )
call sub( x )
contains
subroutine sub( a )
real, intent(in) :: a( -1:, -2:, -3: )
print *, "lbound(a, dim=1) = ", lbound(a, dim=1)
print *, "lbound(a, dim=2) = ", lbound(a, dim=2)
print *, "lbound(a, dim=3) = ", lbound(a, dim=3)
print *, a
end subroutine
end
The program based on above source can produce the following output:
lbound(a, dim=1) = -1
lbound(a, dim=2) = -2
lbound(a, dim=3) = -3
1.000000 2.000000 3.000000 4.000000 5.000000
6.000000 7.000000 8.000000 9.000000 10.00000
11.00000 12.00000 13.00000 14.00000 15.00000
16.00000 17.00000 18.00000 19.00000 20.00000
21.00000 22.00000 23.00000 24.00000
[toc] | [prev] | [next] | [standalone]
| From | Thomas Koenig <tkoenig@netcologne.de> |
|---|---|
| Date | 2022-08-27 22:22 +0000 |
| Message-ID | <tee5f1$cqm$3@newsreader4.netcologne.de> |
| In reply to | #73527 |
d thiebaud <thiebauddick2@aol.com> schrieb:
> On 8/27/22 01:47, Thomas Koenig wrote:
>> Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
>>> “Why do arrays start at 0?"
>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/
>>>
>>> "It's not the reason you think. No, it's not that reason either.”
>>>
>>> My Fortran starts at one. My C++ starts at zero. This has made my life
>>> hell.
>>
>> If you want to declare your Fortran arrays to start at zero, just
>> declare them with a lower bound of zero, like
>>
>> real, dimension(0:n-1) :: a
>
> Can you declare other lower bounds the same way?
Yes.
You can, since 1991, when Fortran 90 was released, do
real, dimension(from:to) :: a
where from and to are arbitrary integer expressions. (If to <
from, then you get a zero-sized array, which is perfectly valid
and which just happens to have size zero and no element).
(In Fortran, you cannot declare variables in the middle of
code. If you want to do that, Fortran 2008 introduced the
BLOCK construct for declaring variables, much like
C's or C++'s { and }, so you can do
read (*,*) from, to
block
real, dimension(from:to) :: a
! Use a here
end block
[toc] | [prev] | [next] | [standalone]
| From | "Fred. Zwarts" <F.Zwarts@KVI.nl> |
|---|---|
| Date | 2022-08-27 21:26 +0200 |
| Message-ID | <tedr4l$1cc0$1@gioia.aioe.org> |
| In reply to | #73508 |
Op 26.aug..2022 om 22:49 schreef Lynn McGuire: > “Why do arrays start at 0?" > https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ > > "It's not the reason you think. No, it's not that reason either.” > > My Fortran starts at one. My C++ starts at zero. This has made my life > hell. > > Lynn > I assumed that it was done because in C x[i] is equivalent to *(x+i).
[toc] | [prev] | [next] | [standalone]
| From | Lynn McGuire <lynnmcguire5@gmail.com> |
|---|---|
| Date | 2022-08-27 15:01 -0500 |
| Message-ID | <tedt6n$757$1@gioia.aioe.org> |
| In reply to | #73528 |
On 8/27/2022 2:26 PM, Fred. Zwarts wrote: > Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >> “Why do arrays start at 0?" >> >> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >> >> "It's not the reason you think. No, it's not that reason either.” >> >> My Fortran starts at one. My C++ starts at zero. This has made my >> life hell. >> >> Lynn >> > > I assumed that it was done because in C x[i] is equivalent to *(x+i). Yup. So Fortran x(i) is equivalent to *(x+i-1). Or, the x is subtracted from first: x--; *(x+i);. Lynn
[toc] | [prev] | [next] | [standalone]
| From | Thomas Koenig <tkoenig@netcologne.de> |
|---|---|
| Date | 2022-08-27 22:24 +0000 |
| Message-ID | <tee5i3$cqm$4@newsreader4.netcologne.de> |
| In reply to | #73530 |
Lynn McGuire <lynnmcguire5@gmail.com> schrieb: > On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>> “Why do arrays start at 0?" >>> >>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>> >>> "It's not the reason you think. No, it's not that reason either.” >>> >>> My Fortran starts at one. My C++ starts at zero. This has made my >>> life hell. >>> >>> Lynn >>> >> >> I assumed that it was done because in C x[i] is equivalent to *(x+i). > > Yup. So Fortran x(i) is equivalent to *(x+i-1). To be more precise, x(i) is equivalent to *(x+i-lbound(x,1)) > Or, the x is > subtracted from first: x--; *(x+i);. That's an f2c idiom, which is not valid C, AFAIK, because the pointer would point before the actual array.
[toc] | [prev] | [next] | [standalone]
| From | John <urbanjost@comcast.net> |
|---|---|
| Date | 2022-08-27 19:34 -0700 |
| Message-ID | <89c35cfc-1eb3-4b37-95c0-55c0cc601d90n@googlegroups.com> |
| In reply to | #73533 |
Oversimplifying a bit, but if you are using non-default starting indices for the first time it is important to know there is a difference in how the ranges will appear in a called procedure when the passed array is an intrinsic type and when it is a component of a user-defined type ... Note that when you specify local bounds for intrinsic types it applies just to the current scope, which is often just the procedure you declared it in. This makes sense or everything you passed the array to would then be required to handle the non-standard dimensioning for a relatively rare case. So if you declared something to have indices from -50 to 50 and then passed it to another procedure, the other procedure sees it as going from 1 to 101. That is, the called procedure sees it as if declared with a default starting index of 1. With user-defined types that is not the case; so generally if you want something to retain its non-standard starting index when being passed it is easiest to declare a special type. It makes sense, but might not be intuitively what you would guess at first. > program main > implicit none > ! these indices are seen in local scope > integer :: cartesian(-50:50,-50:50) > > type cart > ! these indices are seen even in called procedures > integer :: data(-50:50,-50:50) > end type > type(cart) :: cartesian_t > > write(*,*)lbound(cartesian),ubound(cartesian) > write(*,*)lbound(cartesian_t%data),ubound(cartesian_t%data) > > call lookatbounds(cartesian,cartesian_t) > > contains > subroutine lookatbounds(array,array_t) > integer :: array(:,:) > type(cart) :: array_t > > write(*,*)'in called procedure' > write(*,*)lbound(array),ubound(array) > write(*,*)lbound(array_t%data),ubound(array_t%data) > > end subroutine lookatbounds > end program main > -50 -50 50 50 > -50 -50 50 50 > In called procedure > 1 1 101 101 > -50 -50 50 50
[toc] | [prev] | [next] | [standalone]
| From | Robin Vowels <robin.vowels@gmail.com> |
|---|---|
| Date | 2022-08-28 01:50 -0700 |
| Message-ID | <b9b2702a-94d2-4a83-bc1e-1337470dc884n@googlegroups.com> |
| In reply to | #73534 |
On Sunday, August 28, 2022 at 12:34:29 PM UTC+10, John wrote: > Oversimplifying a bit, but if you are using non-default starting indices for the first > time it is important to know there is a difference in how the ranges will appear in > a called procedure when the passed array is an intrinsic type and when it is a component > of a user-defined type ... > > Note that when you specify local bounds for intrinsic types it applies > just to the current scope, which is often just the procedure you declared > it in. This makes sense or everything you passed the array to would then > be required to handle the non-standard dimensioning for a relatively > rare case. > > So if you declared something to have indices from -50 to 50 and then > passed it to another procedure, the other procedure sees it as going > from 1 to 101. That is, the called procedure sees it as if declared with > a default starting index of 1. You cater for this by passing the lower bound along with the array in question. Then, in the called procedure, the bounds are still -50 to +50. > With user-defined types that is not the case; so generally if you want > something to retain its non-standard starting index when being passed > it is easiest to declare a special type. > > It makes sense, but might not be intuitively what you would guess > at first. > > > program main > > implicit none > > ! these indices are seen in local scope > > integer :: cartesian(-50:50,-50:50) > > > > type cart > > ! these indices are seen even in called procedures > > integer :: data(-50:50,-50:50) > > end type > > type(cart) :: cartesian_t > > > > write(*,*)lbound(cartesian),ubound(cartesian) > > write(*,*)lbound(cartesian_t%data),ubound(cartesian_t%data) > > > > call lookatbounds(cartesian,cartesian_t) > > > > contains > > subroutine lookatbounds(array,array_t) > > integer :: array(:,:) > > type(cart) :: array_t > > > > write(*,*)'in called procedure' > > write(*,*)lbound(array),ubound(array) > > write(*,*)lbound(array_t%data),ubound(array_t%data) > > > > end subroutine lookatbounds > > end program main > > > -50 -50 50 50 > > -50 -50 50 50 > > In called procedure > > 1 1 101 101 > > -50 -50 50 50
[toc] | [prev] | [next] | [standalone]
| From | Lynn McGuire <lynnmcguire5@gmail.com> |
|---|---|
| Date | 2022-08-27 22:40 -0500 |
| Message-ID | <teeo2r$8tl$1@gioia.aioe.org> |
| In reply to | #73533 |
On 8/27/2022 5:24 PM, Thomas Koenig wrote: > Lynn McGuire <lynnmcguire5@gmail.com> schrieb: >> On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>>> “Why do arrays start at 0?" >>>> >>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>>> >>>> "It's not the reason you think. No, it's not that reason either.” >>>> >>>> My Fortran starts at one. My C++ starts at zero. This has made my >>>> life hell. >>>> >>>> Lynn >>>> >>> >>> I assumed that it was done because in C x[i] is equivalent to *(x+i). >> >> Yup. So Fortran x(i) is equivalent to *(x+i-1). > > To be more precise, x(i) is equivalent to *(x+i-lbound(x,1)) > >> Or, the x is >> subtracted from first: x--; *(x+i);. > > That's an f2c idiom, which is not valid C, AFAIK, because > the pointer would point before the actual array. While the second pointer is a bad pointer, it is not a illegal pointer. Variables can point to anywhere, they are not illegal until referenced. Otherwise, code would be crashing all over the place. If I malloc'd some space, then free'd the space, and did not NULL the pointer, that dangling pointer would crash if ever referenced (hopefully) but not if it just hangs around. I wish that C/C++ would provide some sort of pointer validation but it does not. I keep track of my pointers for that reason and validate them before using when I have some error prone code. In 850,000 lines of F77 and 30,000 lines of C/C++ code, I have suspicious pointers in several areas due to programmers suballocating malloc'd space and forgetting to nullify those suballocated pointers after freeing the allocated space. Old code, you gotta love it. Lynn
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-08-27 22:07 -0700 |
| Message-ID | <878rn9j6r4.fsf@nosuchdomain.example.com> |
| In reply to | #73535 |
Lynn McGuire <lynnmcguire5@gmail.com> writes:
> On 8/27/2022 5:24 PM, Thomas Koenig wrote:
>> Lynn McGuire <lynnmcguire5@gmail.com> schrieb:
>>> On 8/27/2022 2:26 PM, Fred. Zwarts wrote:
>>>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire:
>>>>> “Why do arrays start at 0?"
>>>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/
>>>>>
>>>>> "It's not the reason you think. No, it's not that reason either.”
>>>>>
>>>>> My Fortran starts at one. My C++ starts at zero. This has made my
>>>>> life hell.
>>>>
>>>> I assumed that it was done because in C x[i] is equivalent to *(x+i).
>>>
>>> Yup. So Fortran x(i) is equivalent to *(x+i-1).
>> To be more precise, x(i) is equivalent to *(x+i-lbound(x,1))
>>
>>> Or, the x is
>>> subtracted from first: x--; *(x+i);.
>> That's an f2c idiom, which is not valid C, AFAIK, because
>> the pointer would point before the actual array.
>
> While the second pointer is a bad pointer, it is not a illegal
> pointer. Variables can point to anywhere, they are not illegal until
> referenced. Otherwise, code would be crashing all over the place. If
> I malloc'd some space, then free'd the space, and did not NULL the
> pointer, that dangling pointer would crash if ever referenced
> (hopefully) but not if it just hangs around.
Computing a pointer before the beginning of an array causes undefined
behavior in C and C++, even if you never dereference it.
[...]
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | gah4 <gah4@u.washington.edu> |
|---|---|
| Date | 2022-08-27 23:04 -0700 |
| Message-ID | <9b7a793e-ed7c-436e-95d6-0c6a79e220cfn@googlegroups.com> |
| In reply to | #73536 |
On Saturday, August 27, 2022 at 10:07:34 PM UTC-7, Keith Thompson wrote:
> Lynn McGuire <lynnmc...@gmail.com> writes:
(snip)
> > While the second pointer is a bad pointer, it is not a illegal
> > pointer. Variables can point to anywhere, they are not illegal until
> > referenced. Otherwise, code would be crashing all over the place. If
> > I malloc'd some space, then free'd the space, and did not NULL the
> > pointer, that dangling pointer would crash if ever referenced
> > (hopefully) but not if it just hangs around.
> Computing a pointer before the beginning of an array causes undefined
> behavior in C and C++, even if you never dereference it.
There might be some hardware, where something especially bad could happen.
I don't know of any such hardware.
The biggest problem, though, is that it might fail conditional tests.
If the original pointer is at the beginning of memory, or in a segmented
memory model, at the beginning of a segment, then it will (likely) wrap.
The restriction, for example, disallows code like:
for(p=start+10; p>=start; p--) putchar(*p);
As p could be a pointer to a large structure, it would be difficult for the system
to ensure it didn't wrap.
On the other hand, C does guarantee a pointer can point just past the end.
That does allow for loops like:
for(p=start; p<=end; p++) putchar(*p);
In this case, in the usual implementation, p could be one memory unit
past the end, even for a large struct.
This does have some inconvenience. For memory models like large
mode 16 bit x86 code, you can't allocate the whole segment
of 65536 bytes. There are times when a table that size could
be very useful.
And for the statement above, "but not if it just hangs around".
It is true that such pointers can "just hang around". But if, for example,
you assign them to another variable, or compare them with another
pointer, they are not "just hanging around".
In the 80286 days, I did much protected mode 80286 code with OS/2
version 1.0 and 1.2. Loading an invalid segment selector into a segment
register generates a protection fault, even if you don't dereference it.
Compilers I know never do that. Assignment is done without loading
into a segment register, and also comparison. Comparisons other
than for equal or not-equal only compare the offset.
In any case, yes C doesn't allow decrementing pointers past the
start of the allocated memory. Most users that do it won't do the
pointer comparisons above. They can decide for themselves,
whether it is a problem to worry about.
[toc] | [prev] | [next] | [standalone]
| From | Thomas Koenig <tkoenig@netcologne.de> |
|---|---|
| Date | 2022-08-28 07:50 +0000 |
| Message-ID | <tef6nk$1go$1@newsreader4.netcologne.de> |
| In reply to | #73535 |
Lynn McGuire <lynnmcguire5@gmail.com> schrieb: > On 8/27/2022 5:24 PM, Thomas Koenig wrote: >> Lynn McGuire <lynnmcguire5@gmail.com> schrieb: >>> On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >>>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>>>> “Why do arrays start at 0?" >>>>> >>>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>>>> >>>>> "It's not the reason you think. No, it's not that reason either.” >>>>> >>>>> My Fortran starts at one. My C++ starts at zero. This has made my >>>>> life hell. >>>>> >>>>> Lynn >>>>> >>>> >>>> I assumed that it was done because in C x[i] is equivalent to *(x+i). >>> >>> Yup. So Fortran x(i) is equivalent to *(x+i-1). >> >> To be more precise, x(i) is equivalent to *(x+i-lbound(x,1)) >> >>> Or, the x is >>> subtracted from first: x--; *(x+i);. >> >> That's an f2c idiom, which is not valid C, AFAIK, because >> the pointer would point before the actual array. > > While the second pointer is a bad pointer, it is not a illegal pointer. > Variables can point to anywhere, they are not illegal until referenced. Unfortunately not. Looking at n2596.pdf, one finds under J.2, "Undefined behavior", — Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6). > Otherwise, code would be crashing all over the place. Undefined behavior does not mean that the code will reliably crash. It just says that the C standard gives no guarantee about what will happen, and, even if it works right now, such code is at the mercy of future compiler revisions, cosmic rays, and other forseen and unforseen circumstances.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-08-28 11:52 +0200 |
| Message-ID | <tefdsv$jj2g$1@dont-email.me> |
| In reply to | #73540 |
On 28/08/2022 09:50, Thomas Koenig wrote: > Lynn McGuire <lynnmcguire5@gmail.com> schrieb: >> On 8/27/2022 5:24 PM, Thomas Koenig wrote: >>> Lynn McGuire <lynnmcguire5@gmail.com> schrieb: >>>> On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >>>>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>>>>> “Why do arrays start at 0?" >>>>>> >>>>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>>>>> >>>>>> "It's not the reason you think. No, it's not that reason either.” >>>>>> >>>>>> My Fortran starts at one. My C++ starts at zero. This has made my >>>>>> life hell. >>>>>> >>>>>> Lynn >>>>>> >>>>> >>>>> I assumed that it was done because in C x[i] is equivalent to *(x+i). >>>> >>>> Yup. So Fortran x(i) is equivalent to *(x+i-1). >>> >>> To be more precise, x(i) is equivalent to *(x+i-lbound(x,1)) >>> >>>> Or, the x is >>>> subtracted from first: x--; *(x+i);. >>> >>> That's an f2c idiom, which is not valid C, AFAIK, because >>> the pointer would point before the actual array. >> >> While the second pointer is a bad pointer, it is not a illegal pointer. >> Variables can point to anywhere, they are not illegal until referenced. > > Unfortunately not. > > Looking at n2596.pdf, one finds under J.2, "Undefined behavior", > > — Addition or subtraction of a pointer into, or just beyond, > an array object and an integer type produces a result that does > not point into, or just beyond, the same array object (6.5.6). > >> Otherwise, code would be crashing all over the place. > > Undefined behavior does not mean that the code will reliably crash. > It just says that the C standard gives no guarantee about what will > happen, and, even if it works right now, such code is at the mercy > of future compiler revisions, cosmic rays, and other forseen and > unforseen circumstances. Indeed. C was designed to have as few restrictions on the hardware as it could, while still having a minimum feature set. If you have a segmented memory architecture (such as x86), then addresses might have a form "segment:offset". If an array starts at offset 0, what does it mean to have an address one before that? It might make no sense, or have different meanings in different contexts, or require inefficient extra instructions to get right. Some architectures pre-load information about memory pages or segments when a pointer register is loaded, causing trouble if it does not actually point to valid memory. Leaving this all undefined is much simpler for everyone. (The other end, one past the end of the array, is too useful in common C idioms to leave undefined - even if it might mean that an implementation can't use the last address in memory.)
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-08-28 19:43 +0300 |
| Message-ID | <teg5v0$lrls$1@dont-email.me> |
| In reply to | #73535 |
28.08.2022 06:40 Lynn McGuire kirjutas: > On 8/27/2022 5:24 PM, Thomas Koenig wrote: >> Lynn McGuire <lynnmcguire5@gmail.com> schrieb: >>> On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >>>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>>>> “Why do arrays start at 0?" >>>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>>>> >>>>> "It's not the reason you think. No, it's not that reason either.” >>>>> >>>>> My Fortran starts at one. My C++ starts at zero. This has made my >>>>> life hell. >>>>> >>>>> Lynn >>>>> >>>> >>>> I assumed that it was done because in C x[i] is equivalent to *(x+i). >>> >>> Yup. So Fortran x(i) is equivalent to *(x+i-1). >> >> To be more precise, x(i) is equivalent to *(x+i-lbound(x,1)) >> >>> Or, the x is >>> subtracted from first: x--; *(x+i);. >> >> That's an f2c idiom, which is not valid C, AFAIK, because >> the pointer would point before the actual array. > > While the second pointer is a bad pointer, it is not a illegal pointer. The C++ standard (n4861) calls this "an invalid pointer value". For pointers which continue to point to freed objects, it says "A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration". About invalid pointers it says: "Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior." There is also a footnote: "Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault." So, while technically one might get away with the "x--" trick most of the time with the linear memory addressing used by mainstream implementations nowadays, still various diagnostic tools would mark these as invalid pointers, causing an avalanche of errors whenever you want to solve your actual memory access problems. I guess it might also subvert automatic garbage collection which is sometimes used with C++. There is a special case of "safely-derived" pointer values which I suspect is made exactly for making GC possible, and changing the pointer value to x-1 would apparently ruin this. And with segmented memory, like with 16-bit x86, it might cause all kind of surprises.
[toc] | [prev] | [next] | [standalone]
| From | "Fred. Zwarts" <F.Zwarts@KVI.nl> |
|---|---|
| Date | 2022-08-28 10:01 +0200 |
| Message-ID | <tef7ci$12uj$1@gioia.aioe.org> |
| In reply to | #73530 |
Op 27.aug..2022 om 22:01 schreef Lynn McGuire: > On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>> “Why do arrays start at 0?" >>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>> >>> "It's not the reason you think. No, it's not that reason either.” >>> >>> My Fortran starts at one. My C++ starts at zero. This has made my >>> life hell. >>> >>> Lynn >>> >> >> I assumed that it was done because in C x[i] is equivalent to *(x+i). > > Yup. So Fortran x(i) is equivalent to *(x+i-1). Or, the x is > subtracted from first: x--; *(x+i);. > > Lynn > I don't understand the idea of x--. Why modifying x? What happens if x is indexed later again?
[toc] | [prev] | [next] | [standalone]
| From | Thomas Koenig <tkoenig@netcologne.de> |
|---|---|
| Date | 2022-08-28 08:14 +0000 |
| Message-ID | <tef85g$28i$1@newsreader4.netcologne.de> |
| In reply to | #73541 |
Fred. Zwarts <F.Zwarts@KVI.nl> schrieb: > Op 27.aug..2022 om 22:01 schreef Lynn McGuire: >> On 8/27/2022 2:26 PM, Fred. Zwarts wrote: >>> Op 26.aug..2022 om 22:49 schreef Lynn McGuire: >>>> “Why do arrays start at 0?" >>>> https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ >>>> >>>> "It's not the reason you think. No, it's not that reason either.” >>>> >>>> My Fortran starts at one. My C++ starts at zero. This has made my >>>> life hell. >>>> >>>> Lynn >>>> >>> >>> I assumed that it was done because in C x[i] is equivalent to *(x+i). >> >> Yup. So Fortran x(i) is equivalent to *(x+i-1). Or, the x is >> subtracted from first: x--; *(x+i);. >> >> Lynn >> > > I don't understand the idea of x--. Why modifying x? What happens if x > is indexed later again? The idea is to use this modified pointer for one-based array accesses, so that it would be possible to translate Fortran's A(1) into a[1] on the C side, or A(N) into a[n]. The correct way to do this according to the C standard would be to translate A(N) into a[n-1] on the C side. There are several reasons why this might not have been done: Readability of the generated code (although f2c code is already hard to read), because it made the code slower with compilers of the day, and probably because it "just worked" with the compilers.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-08-28 11:07 +0200 |
| Message-ID | <tefb7v$javh$1@dont-email.me> |
| In reply to | #73508 |
Am 26.08.2022 um 22:49 schrieb Lynn McGuire: > “Why do arrays start at 0?" > https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ > > "It's not the reason you think. No, it's not that reason either.” > > My Fortran starts at one. My C++ starts at zero. This has made my life > hell. > > Lynn On the CPU-level you heave the least number of calculations to determine an address of an indexed entity if the index starts at zero.
[toc] | [prev] | [next] | [standalone]
| From | gah4 <gah4@u.washington.edu> |
|---|---|
| Date | 2022-08-28 02:55 -0700 |
| Message-ID | <b31143ef-9007-45c3-b311-d200a8d364b0n@googlegroups.com> |
| In reply to | #73544 |
On Sunday, August 28, 2022 at 2:07:15 AM UTC-7, Bonita Montero wrote: > Am 26.08.2022 um 22:49 schrieb Lynn McGuire: > > “Why do arrays start at 0?" (snip) > On the CPU-level you heave the least number of calculations to > determine an address of an indexed entity if the index starts > at zero. In many cases, the offset can be set at compile time. In others, it can be done once, such as when an array is allocated.
[toc] | [prev] | [next] | [standalone]
| From | Robin Vowels <robin.vowels@gmail.com> |
|---|---|
| Date | 2022-08-28 05:47 -0700 |
| Message-ID | <2dce1a40-6823-4434-8b94-b0e50d65c4ccn@googlegroups.com> |
| In reply to | #73544 |
On Sunday, August 28, 2022 at 7:07:15 PM UTC+10, Bonita Montero wrote: > Am 26.08.2022 um 22:49 schrieb Lynn McGuire: > > “Why do arrays start at 0?" > > https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ > > > > "It's not the reason you think. No, it's not that reason either.” > > > > My Fortran starts at one. My C++ starts at zero. This has made my life > > hell. . > On the CPU-level you heave the least number of calculations to > determine an address of an indexed entity if the index starts > at zero. . It doesn't follow. In Optimising PL/I for CDC Cyber, matrix indexing consisted of table lookup for the virtual origin of each row (in order to eliminate a slow multiplication). . In DEUCE PL/I, it isn't true for whole array operations, in which the starting address is the address of the first element. For general subscripted references, any offset is computed at compile time. . And even if an adjustment were required at run time, a decrement instruction is one of the shortest and fastest instructions.
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-08-29 11:15 +0000 |
| Subject | Re: ???Why do arrays start at 0?" |
| Message-ID | <tei759$19qc$1@gioia.aioe.org> |
| In reply to | #73508 |
In comp.lang.c++ Lynn McGuire <lynnmcguire5@gmail.com> wrote: > ???Why do arrays start at 0?" > https://buttondown.email/hillelwayne/archive/why-do-arrays-start-at-0/ > > "It's not the reason you think. No, it's not that reason either.??? > > My Fortran starts at one. My C++ starts at zero. This has made my life > hell. I don't know if it's the *original* reason, but I would assume that at least in C one of the main reasons is the principle of maximum efficiency. In many processor architectures the concept of "array" exists, at least when it comes to values of the register sizes (ie. usually 1-byte, 2-byte, 4-byte and 8-byte elements, the last one at least on 64-bit architectures). Prominently the concept of an indexable array exists in the x86 architecture. (I don't remember now if it also exists in the ARM architecture, but I would guess so.) Generally when a processor architecture supports the concept of an "array", it does so by having instructions that take (at least) two registers as the input or the output parameter: A base address, and an offset. The memory location of the element is calculated by adding those two. (The number of bytes that an offset of 1 jumps depends on the instruction, and thus multi-byte elements are supported.) Thus zero-indexing is extraordinarily natural in processor architectures: The "index" is actually an offset. It's a value you add to the base address in order to get to the location you want. Thus, the first element is at index/offset 0. Since that's the case, the most optimal way to handle low-level arrays is to have 0-based indexing in the programming language as well. That way you don't need to be subtracting 1 from the index every time an array is accessed (or you don't need an extraneous unused element at the beginning of the array, consuming memory for no reason). Also, since C supports pointer arithmetic, many operations become simpler. Such as getting the index of an element when what you have is a pointer to it (and the pointer to the start of the array).
[toc] | [prev] | [next] | [standalone]
| From | gah4 <gah4@u.washington.edu> |
|---|---|
| Date | 2022-08-29 22:59 -0700 |
| Subject | Re: ???Why do arrays start at 0?" |
| Message-ID | <317d57ec-0fbe-476a-98b9-a33f4c369b1bn@googlegroups.com> |
| In reply to | #73564 |
On Monday, August 29, 2022 at 4:16:00 AM UTC-7, Juha Nieminen wrote: (snip) > I don't know if it's the *original* reason, but I would assume that at least > in C one of the main reasons is the principle of maximum efficiency. > In many processor architectures the concept of "array" exists, at least > when it comes to values of the register sizes (ie. usually 1-byte, > 2-byte, 4-byte and 8-byte elements, the last one at least on 64-bit > architectures). Prominently the concept of an indexable array exists > in the x86 architecture. (I don't remember now if it also exists in > the ARM architecture, but I would guess so.) BCPL, a predecessor of C, was written on a word addressable machine. Pointer arithmetic was integer arithmetic. It was with C that variables could be larger than the addressable unit, and that pointers (addresses) incremented and decremented in appropriate sized units. In any case, early C (and B and BCPL) programmers were likely also assembly programmers, and would have been used to 0 origin indexing. > Generally when a processor architecture supports the concept of an "array", > it does so by having instructions that take (at least) two registers as > the input or the output parameter: A base address, and an offset. The > memory location of the element is calculated by adding those two. (The > number of bytes that an offset of 1 jumps depends on the instruction, > and thus multi-byte elements are supported.) For many machines, you have to multiply by the element size, but yes some do it for you. C pointer arithmetic is defined in terms of the size of the pointed-to object, and array indexing is defined in terms of pointer arithmetic. > Thus zero-indexing is extraordinarily natural in processor architectures: > The "index" is actually an offset. It's a value you add to the base > address in order to get to the location you want. Thus, the first element > is at index/offset 0. > Since that's the case, the most optimal way to handle low-level arrays is > to have 0-based indexing in the programming language as well. That way > you don't need to be subtracting 1 from the index every time an array is > accessed (or you don't need an extraneous unused element at the beginning > of the array, consuming memory for no reason). In the case of Fortran, starting with static arrays, the compiler can subtract before generating the address constant, such that the subtract is done at compile time. No run-time cost. For allocatable arrays, it can adjust the offset once, and use that. For automatic variables on the stack, the stack pointer offset is computed once. The way C pointers are defined, that would not be quite as easy to do. Or, C pointers are defined the way they are to make it easier. Fortran was originally Formula Translation, and mathematicians did, and still do, use 1 based indexing for matrices and vectors. > Also, since C supports pointer arithmetic, many operations become simpler. > Such as getting the index of an element when what you have is a pointer to > it (and the pointer to the start of the array). Note that it gets more interesting for Fortran. When you pass an array as an argument to a subroutine, it loses the original origin. (Well, most of the time. Remembering when it does and doesn't is probably harder than figuring out 0 vs.1 origin.) One that C programmers like to do, and I suspect was faster on many early machines, is index through arrays with a pointer to an array, indexing it as it goes. That means no subscript calculation in the loop. Many early C processors didn't have multiply, or had slow multiply. However, one of the favorite optimizations for Fortran compilers is strength reduction, converting multiply inside a loop into addition as the loop increments. The result is pretty much the same.
[toc] | [prev] | [standalone]
Page 3 of 3 — ← Prev page 1 2 [3]
Back to top | Article view | comp.lang.fortran
csiph-web