Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

“Why do arrays start at 0?"

230 views
Skip to first unread message

Lynn McGuire

unread,
Aug 26, 2022, 4:49:55 PM8/26/22
to
“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

Gary Scott

unread,
Aug 26, 2022, 5:56:51 PM8/26/22
to
Fortran was there first...and got it right...you can change Fortran to
start at other index values for many cases.

Louis Krupp

unread,
Aug 26, 2022, 6:08:24 PM8/26/22
to
Here's a crude outline of a solution:

If you want a C++ array index to start at 1, make the array one element
bigger than necessary, and start indexing at 1, just like in Fortran.
Element 0 will be unused.

If you want a C++ array to map exactly to a Fortran array, but with an
index starting at 1, wrap the C++ array in a class and overload the
subscripting operator(s) to subtract 1 from the index.

Neither of these approaches seems elegant, but one of them should be
less hellish than the other.

Louis

Mr Flibble

unread,
Aug 26, 2022, 7:44:50 PM8/26/22
to
Fortran is retarded.

/Flibble

Mr Flibble

unread,
Aug 26, 2022, 7:46:05 PM8/26/22
to
Being first doesn't make you correct. Fortran is retarded.

/Flibble

gah4

unread,
Aug 26, 2022, 9:24:07 PM8/26/22
to
On Friday, August 26, 2022 at 2:56:51 PM UTC-7, Gary Scott wrote:

(snip)
> Fortran was there first...and got it right...you can change Fortran to
> start at other index values for many cases.

ALGOL 60 has the [lower:upper] form, presumably back to 1960.

I have, at least a few times, converted programs from one to the other,
and yes it is amazingly easy to get wrong.

d thiebaud

unread,
Aug 26, 2022, 10:30:05 PM8/26/22
to
A reasonable language would let you specify the lower index. Fortran
and C are both retarded.

gah4

unread,
Aug 26, 2022, 10:34:48 PM8/26/22
to
On Friday, August 26, 2022 at 7:30:05 PM UTC-7, d thiebaud wrote:

(snip)

> A reasonable language would let you specify the lower index. Fortran
> and C are both retarded.

Since it hasn't been mentioned yet, note the complication with
Fortran of subroutine arguments. Sometimes the dummy array
has origin 1, even when the actual argument doesn't. Sometimes.

Not that there is an easy answer, but it is a very confusing part
of Fortran arrays.

Robin Vowels

unread,
Aug 26, 2022, 11:31:37 PM8/26/22
to
.
FORTRAN followed centuries-old mathematical convention.
FORTRAN started at 1 for subscripts.
It's now been the default, since lower bounds were introduced.

PL/I has always allowed lower bounds other than 1,
the default being 1.

Robin Vowels

unread,
Aug 26, 2022, 11:34:26 PM8/26/22
to
On Saturday, August 27, 2022 at 12:30:05 PM UTC+10, d thiebaud wrote:

> A reasonable language would let you specify the lower index. Fortran
> and C are both retarded.
.
Fortran allowes the lower bound to be specified.

Keith Thompson

unread,
Aug 27, 2022, 1:05:23 AM8/27/22
to
"Mr Flibble" is a troll, and I'm sure he's aware that "retarded" is an
offensive word. Are you?

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

Thomas Koenig

unread,
Aug 27, 2022, 1:47:47 AM8/27/22
to
Lynn McGuire <lynnmc...@gmail.com> schrieb:
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

fiz...@gmail.com

unread,
Aug 27, 2022, 4:48:15 AM8/27/22
to
On Saturday, August 27, 2022 at 5:31:37 AM UTC+2, Robin Vowels wrote:
> On Saturday, August 27, 2022 at 6:49:55 AM UTC+10, Lynn McGuire wrote:
> FORTRAN followed centuries-old mathematical convention.
Nope. Just as the linked article mentions, in Mathematics, starting an index from 0 or 1 are both often used, e.g., for elements of sequences and series, 0 seems to be most often used, for vector and matrix indices, 1. If a convergence of a sequence is considered, you often don't care about "early" elements, so, if that yields a simple formula, you start from any number convenient. In Physics, you often start vector and matrix indices with 0 if the zeroth component is in some sense distinguished (e.g., in relativistic theories, distinguishing the time-like coordinate from the 3 space-like ones).

gah4

unread,
Aug 27, 2022, 5:18:00 AM8/27/22
to
On Saturday, August 27, 2022 at 1:48:15 AM UTC-7, fiz...@gmail.com wrote:
> On Saturday, August 27, 2022 at 5:31:37 AM UTC+2, Robin Vowels wrote:
> > On Saturday, August 27, 2022 at 6:49:55 AM UTC+10, Lynn McGuire wrote:
> > FORTRAN followed centuries-old mathematical convention.
> Nope. Just as the linked article mentions, in Mathematics, starting an index
> from 0 or 1 are both often used, e.g., for elements of sequences and series,
> 0 seems to be most often used, for vector and matrix indices, 1.

Yes, so array indexing is 1. Series sums start at zero, but are not indexed.

> If a convergence of a sequence is considered, you often don't care about
>"early" elements, so, if that yields a simple formula, you start from any
> number convenient.

Now for this case, you want a DO loop to start at zero, which Fortran 66
didn't allow. But you normally sum inside the loop, not store element
in an array.

> In Physics, you often start vector and matrix indices with 0 if the zeroth
> component is in some sense distinguished (e.g., in relativistic theories,
> distinguishing the time-like coordinate from the 3 space-like ones).

Yes, four-vectors.

Thomas Koenig

unread,
Aug 27, 2022, 5:30:15 AM8/27/22
to
gah4 <ga...@u.washington.edu> schrieb:
> On Saturday, August 27, 2022 at 1:48:15 AM UTC-7, fiz...@gmail.com wrote:
>> On Saturday, August 27, 2022 at 5:31:37 AM UTC+2, Robin Vowels wrote:
>> > On Saturday, August 27, 2022 at 6:49:55 AM UTC+10, Lynn McGuire wrote:
>> > FORTRAN followed centuries-old mathematical convention.
>> Nope. Just as the linked article mentions, in Mathematics, starting an index
>> from 0 or 1 are both often used, e.g., for elements of sequences and series,
>> 0 seems to be most often used, for vector and matrix indices, 1.
>
> Yes, so array indexing is 1. Series sums start at zero, but are not indexed.
>
>> If a convergence of a sequence is considered, you often don't care about
>>"early" elements, so, if that yields a simple formula, you start from any
>> number convenient.
>
> Now for this case, you want a DO loop to start at zero, which Fortran 66
> didn't allow.

Really? You mean that

DO 10 I=0,1

would not be allowed?

You probably meant zero-trip loops which were undefined.

Mr Flibble

unread,
Aug 27, 2022, 7:06:14 AM8/27/22
to
On Fri, 26 Aug 2022 22:05:17 -0700
Keith Thompson <Keith.S.T...@gmail.com> wrote:

> d thiebaud <thieba...@aol.com> writes:
> > On 8/26/22 19:46, Mr Flibble wrote:
> >> On Fri, 26 Aug 2022 16:56:47 -0500
> >> Gary Scott <garyl...@sbcglobal.net> wrote:
> >>
> >>> On 8/26/2022 3:49 PM, Lynn McGuire 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.
> >>>>
> >>>> Lynn
> >>>>
> >>> Fortran was there first...and got it right...you can change
> >>> Fortran to start at other index values for many cases.
> >> Being first doesn't make you correct. Fortran is retarded.
> >> /Flibble
> >>
> > A reasonable language would let you specify the lower index. Fortran
> > and C are both retarded.
>
> "Mr Flibble" is a troll, and I'm sure he's aware that "retarded" is an
> offensive word. Are you?

Retarded isn't an offensive word but I could replace it with fucktarded
if that helps?

/Flibble

Robin Vowels

unread,
Aug 27, 2022, 8:16:37 AM8/27/22
to
On Saturday, August 27, 2022 at 6:48:15 PM UTC+10, fiz...@gmail.com wrote:
> On Saturday, August 27, 2022 at 5:31:37 AM UTC+2, Robin Vowels wrote:
> > On Saturday, August 27, 2022 at 6:49:55 AM UTC+10, Lynn McGuire wrote:
> > FORTRAN followed centuries-old mathematical convention.
> Nope. Just as the linked article mentions, in Mathematics, starting an index from 0 or 1 are both often used, e.g., for elements of sequences and series, 0 seems to be most often used,
.
That's irrrelevnt to the OP's question.
.
for vector and matrix indices, 1.

That's what I said.
It's an old tradition.

> If a convergence of a sequence is considered, you often don't care about "early" elements, so, if that yields a simple formula, you start from any number convenient. In Physics, you often start vector and matrix indices with 0
.
Really? See above.
.

Scott Lurndal

unread,
Aug 27, 2022, 10:28:53 AM8/27/22
to
There are around twenty languages that start array indicies with one. None of
them are low-level hardware-oriented languages (Burroughs algol excepted) like C. In the
hardware indicies start at zero by definition.

gah4

unread,
Aug 27, 2022, 1:01:04 PM8/27/22
to
On Saturday, August 27, 2022 at 2:30:15 AM UTC-7, Thomas Koenig wrote:

(snip)

> > Now for this case, you want a DO loop to start at zero, which Fortran 66
> > didn't allow.

> Really? You mean that

> DO 10 I=0,1

> would not be allowed?

Yes, not allowed. And the IBM compilers wouldn't compile them
with a constant. BXLE works fine with variables, though.
That was another change in Fortran 77.

> You probably meant zero-trip loops which were undefined.

And yes, even though the standard said undefined, many compilers
implemented the one-trip minimum, with the test at the end.
And so many believed that was required.



d thiebaud

unread,
Aug 27, 2022, 3:19:26 PM8/27/22
to
Can you declare other lower bounds the same way?

Fred. Zwarts

unread,
Aug 27, 2022, 3:26:26 PM8/27/22
to
Op 26.aug..2022 om 22:49 schreef Lynn McGuire:
I assumed that it was done because in C x[i] is equivalent to *(x+i).

FortranFan

unread,
Aug 27, 2022, 3:45:28 PM8/27/22
to
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

Lynn McGuire

unread,
Aug 27, 2022, 4:01:34 PM8/27/22
to
Yup. So Fortran x(i) is equivalent to *(x+i-1). Or, the x is
subtracted from first: x--; *(x+i);.

Lynn

Thomas Koenig

unread,
Aug 27, 2022, 6:13:09 PM8/27/22
to
gah4 <ga...@u.washington.edu> schrieb:
> On Saturday, August 27, 2022 at 2:30:15 AM UTC-7, Thomas Koenig wrote:
>
> (snip)
>
>> > Now for this case, you want a DO loop to start at zero, which Fortran 66
>> > didn't allow.
>
>> Really? You mean that
>
>> DO 10 I=0,1
>
>> would not be allowed?
>
> Yes, not allowed.

I have the Fortran 66 standard before me, and I find no such
restriction in 7.1.2.8 (nor would it make sense at all).

Which part of the standard are you referring to?

Thomas Koenig

unread,
Aug 27, 2022, 6:22:28 PM8/27/22
to
d thiebaud <thieba...@aol.com> schrieb:
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

Thomas Koenig

unread,
Aug 27, 2022, 6:24:06 PM8/27/22
to
Lynn McGuire <lynnmc...@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.

John

unread,
Aug 27, 2022, 10:34:29 PM8/27/22
to
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

Lynn McGuire

unread,
Aug 27, 2022, 11:40:16 PM8/27/22
to
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

Keith Thompson

unread,
Aug 28, 2022, 1:07:34 AM8/28/22
to
Lynn McGuire <lynnmc...@gmail.com> writes:
> On 8/27/2022 5:24 PM, Thomas Koenig wrote:
>> Lynn McGuire <lynnmc...@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.

[...]

gah4

unread,
Aug 28, 2022, 1:26:29 AM8/28/22
to
On Saturday, August 27, 2022 at 3:13:09 PM UTC-7, Thomas Koenig wrote:
> gah4 <ga...@u.washington.edu> schrieb:
> > On Saturday, August 27, 2022 at 2:30:15 AM UTC-7, Thomas Koenig wrote:
(snip)
> >> Really? You mean that

> >> DO 10 I=0,1

> >> would not be allowed?

> > Yes, not allowed.

> I have the Fortran 66 standard before me, and I find no such
> restriction in 7.1.2.8 (nor would it make sense at all).

> Which part of the standard are you referring to?

Yes 7.1.2.8.

"At time of execution of the DO statement, m1, m2, and m3 must be greater than zero."

gah4

unread,
Aug 28, 2022, 2:04:16 AM8/28/22
to
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.



Thomas Koenig

unread,
Aug 28, 2022, 2:59:23 AM8/28/22
to
gah4 <ga...@u.washington.edu> schrieb:
> On Saturday, August 27, 2022 at 3:13:09 PM UTC-7, Thomas Koenig wrote:
>> gah4 <ga...@u.washington.edu> schrieb:
>> > On Saturday, August 27, 2022 at 2:30:15 AM UTC-7, Thomas Koenig wrote:
> (snip)
>> >> Really? You mean that
>
>> >> DO 10 I=0,1
>
>> >> would not be allowed?
>
>> > Yes, not allowed.
>
>> I have the Fortran 66 standard before me, and I find no such
>> restriction in 7.1.2.8 (nor would it make sense at all).
>
>> Which part of the standard are you referring to?
>
> Yes 7.1.2.8.
>
> "At time of execution of the DO statement, m1, m2, and m3 must be greater than zero."

OK, I missed that one.

Big hole, luckily rectified in subsequent versions.

Thomas Koenig

unread,
Aug 28, 2022, 3:50:15 AM8/28/22
to
Lynn McGuire <lynnmc...@gmail.com> schrieb:
> On 8/27/2022 5:24 PM, Thomas Koenig wrote:
>> Lynn McGuire <lynnmc...@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.

Fred. Zwarts

unread,
Aug 28, 2022, 4:01:28 AM8/28/22
to
Op 27.aug..2022 om 22:01 schreef Lynn McGuire:
I don't understand the idea of x--. Why modifying x? What happens if x
is indexed later again?

Thomas Koenig

unread,
Aug 28, 2022, 4:14:44 AM8/28/22
to
Fred. Zwarts <F.Zw...@KVI.nl> schrieb:
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.

Robin Vowels

unread,
Aug 28, 2022, 4:50:31 AM8/28/22
to
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.

Bonita Montero

unread,
Aug 28, 2022, 5:07:15 AM8/28/22
to
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.


David Brown

unread,
Aug 28, 2022, 5:52:35 AM8/28/22
to
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.)

gah4

unread,
Aug 28, 2022, 5:55:52 AM8/28/22
to
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.

Robin Vowels

unread,
Aug 28, 2022, 8:47:05 AM8/28/22
to
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.

Charlie Roberts

unread,
Aug 28, 2022, 10:25:39 AM8/28/22
to
On Fri, 26 Aug 2022 16:56:47 -0500, Gary Scott
<garyl...@sbcglobal.net> wrote:

>On 8/26/2022 3:49 PM, Lynn McGuire 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.
>>
>> Lynn
>>
>Fortran was there first...and got it right...you can change Fortran to
>start at other index values for many cases.

Not sure which universe the OP lives in, but from Fortran 77 onwards
arrays could be indexed as desired by the user. As a starting graduate
students in condensed matter physics, my cohort and myself were
very thankful for this as many quantities are in solid state physics
indexed from -(N/2-1) to N/2. We did not have to do all the
shifting that F66 users did.

Also useful in relativity if you just want to call time the zero-th
dimension and leave 1, 2 and 3 for x, y and z.

It was surprsing when I came across FFT codes that were written
with the shifting of the negavite frequencies to the positive side.
Not a show stopper, but it nice to see code conform to the
formulae when one is a beginner to the field and computing.

Charlie Roberts

unread,
Aug 28, 2022, 10:28:10 AM8/28/22
to
On Fri, 26 Aug 2022 16:08:20 -0600, Louis Krupp
<lkr...@invalid.pssw.com.invalid> wrote:

>On 8/26/2022 2:49 PM, Lynn McGuire 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.
>>
>
>Here's a crude outline of a solution:
>
>If you want a C++ array index to start at 1, make the array one element
>bigger than necessary, and start indexing at 1, just like in Fortran.
>Element 0 will be unused.
>
>If you want a C++ array to map exactly to a Fortran array, but with an
>index starting at 1, wrap the C++ array in a class and overload the
>subscripting operator(s) to subtract 1 from the index.
>
>Neither of these approaches seems elegant, but one of them should be
>less hellish than the other.
>
>Louis

The authors of "Numerical Recipes" started out with F77 and so all the
code in their first book has arrays starting at 1. When they brought
out the C version, they resorted to just this trick!

Thomas Koenig

unread,
Aug 28, 2022, 12:30:08 PM8/28/22
to
Charlie Roberts <crob...@gmail.com> schrieb:
Ugh.

I never read the C (or C++) versions, the latest one I used is
the 2nd edition in Fortran 77 (which I still have within reach at
my desk).

Paavo Helde

unread,
Aug 28, 2022, 12:43:15 PM8/28/22
to
28.08.2022 06:40 Lynn McGuire kirjutas:
> On 8/27/2022 5:24 PM, Thomas Koenig wrote:
>> Lynn McGuire <lynnmc...@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.

Lynn McGuire

unread,
Aug 28, 2022, 2:42:28 PM8/28/22
to
What ? Our code has negative indexes dating back to F66 days. I am
assuming that this is:

DO 10 I = ncp, 1, -1

Lynn

Thomas Koenig

unread,
Aug 28, 2022, 4:17:22 PM8/28/22
to
Lynn McGuire <lynnmc...@gmail.com> schrieb:
Hm. Seems like this was carried over from the very first FORTRAN.
The 1956 Programmer's Reference Manual restricted them to unsigned
fixed point constants.

Looking at the Fortran IV language at
http://www.bitsavers.org/pdf/ibm/360/fortran/C28-6515-6_FORTRAN_IV_Language_1966.pdf
we have the same restriction.

So, seems like an extension at the time (a very useful one, too).

gah4

unread,
Aug 28, 2022, 5:05:08 PM8/28/22
to
On Sunday, August 28, 2022 at 11:42:28 AM UTC-7, Lynn McGuire wrote:
> On 8/28/2022 12:26 AM, gah4 wrote:

(snip, I wrote)

> > "At time of execution of the DO statement, m1, m2, and m3 must be greater than zero."

> What ? Our code has negative indexes dating back to F66 days. I am
> assuming that this is:

> DO 10 I = ncp, 1, -1

Many systems had extensions to Fortran 66, and that might not have been unusual.

Those competing with IBM needed a way to make there systems look better,
and such extensions were one way to do it. DEC had a lot of extensions like that.

On the other hand, IBM was careful with theirs. The had some big extensions
where there was no way around them. END= on READ was very useful!

But DO look changes that were easy to make with a temporary variable
did not get an extension. Making m3 negative means that the test
has to be inverted. IBM Fortran IV compilers don't change the test.

As note, though, IBM Fortran IV compilers will also disallow:

DO 10 I=0,9

though if you use a variable set to 0, it works just fine.
(Unless the optimizer figures it out, and disallows it.)

Similarly,

DO 10 I = ncp, 1, -1

won't compile. If you use a variable set to -1, it will
loop until the variable wraps to a large value.


gah4

unread,
Aug 28, 2022, 5:08:43 PM8/28/22
to
On Sunday, August 28, 2022 at 1:17:22 PM UTC-7, Thomas Koenig wrote:

(snip)

> Hm. Seems like this was carried over from the very first FORTRAN.
> The 1956 Programmer's Reference Manual restricted them to unsigned
> fixed point constants.

> Looking at the Fortran IV language at
> http://www.bitsavers.org/pdf/ibm/360/fortran/C28-6515-6_FORTRAN_IV_Language_1966.pdf
> we have the same restriction.

> So, seems like an extension at the time (a very useful one, too).

It is not so hard to do with a constant, but IBM didn't do that. It is harder
with a variable, as the test direction depends on the sign.

IBM S/360 compilers use BXLE, Branch on indeX Less than or Equal, to
increment and test, at the end of the loop.

IBM was always good at marking their extensions with gray shading in the
manuals.


Robin Vowels

unread,
Aug 29, 2022, 12:53:33 AM8/29/22
to
.
All of these were valid in PL/I from the beginning (1966) --
negative increments, initial values starting at zero or even negative.
.
As well, a PL/I loop could be executed 0 times (inlike FORTRAN
which, at that time, insisted in executing a loop at least once,
even if the initial value was greater than the final value).

Robin Vowels

unread,
Aug 29, 2022, 12:54:50 AM8/29/22
to
.
You might have to wait a long time for that to happen.

Ron Shepard

unread,
Aug 29, 2022, 3:07:13 AM8/29/22
to
On 8/27/22 5:13 PM, Thomas Koenig wrote:
> gah4 <ga...@u.washington.edu> schrieb:
>> On Saturday, August 27, 2022 at 2:30:15 AM UTC-7, Thomas Koenig wrote:
>>
>> (snip)
>>
>>>> Now for this case, you want a DO loop to start at zero, which Fortran 66
>>>> didn't allow.
>>
>>> Really? You mean that
>>
>>> DO 10 I=0,1
>>
>>> would not be allowed?
>>
>> Yes, not allowed.
>
> I have the Fortran 66 standard before me, and I find no such
> restriction in 7.1.2.8 (nor would it make sense at all).
>
> Which part of the standard are you referring to?

It is right there in that section in the paragraph that starts with (3).
The three integers m1, m2, and m3 must be greater than zero.

The only justification I can see for this is that they wanted to be able
to implement the loop logic with unsigned integers. Even then I don't
know why zero was not allowed.

$.02 -Ron Shepard

Ron Shepard

unread,
Aug 29, 2022, 3:42:34 AM8/29/22
to
On 8/28/22 9:28 AM, Charlie Roberts wrote:
[...]
> The authors of "Numerical Recipes" started out with F77 and so all the
> code in their first book has arrays starting at 1. When they brought
> out the C version, they resorted to just this trick!

If I remember correctly, the code in the chapters was written in Pascal,
and there was an appendix that had fortran code. Or maybe it was the
other way around? I don't remember what version of fortran they used, bu
the book was published before there were any f77 compilers available, so
I'm guessing that it was f66+extensions. Then they wrote the f77 version
a year or two later.

So the conventions they were mimicking in C were not really f77 (or even
Pascal), they were standard math conventions. C at that time was not
designed to do math. It did not even respect grouping of operands by
parentheses. This frustrating flaw in the C language would be corrected
some 19 years after the first language definition in the ANSI C version
of the language, c89.

When the NR authors did the pointer decrement hack, they took a lot of
criticism for writing nonstandard code. Then when they wrote the c++
version, they adjusted the math notation to fit the limitations of the
language.

$.02 -Ron Shepard



Robin Vowels

unread,
Aug 29, 2022, 4:30:32 AM8/29/22
to
.
Definitely not.
The control variable at least would be an ordinary signed integer,
because that variable could be used in integer and/or real
expressions.
.
And if m2 and m3 are variables,, then for the same reason,
these would be ordinary signed integers.

gah4

unread,
Aug 29, 2022, 6:48:45 AM8/29/22
to
On Monday, August 29, 2022 at 12:07:13 AM UTC-7, Ron Shepard wrote:

(snip on DO loops)

> It is right there in that section in the paragraph that starts with (3).
> The three integers m1, m2, and m3 must be greater than zero.

> The only justification I can see for this is that they wanted to be able
> to implement the loop logic with unsigned integers. Even then I don't
> know why zero was not allowed.

There are a lot of restrictions in Fortran 66 that aren't at all obvious.

I thought this one went back to Fortran I on the 704, but don't see it there.

Some machines have special hardware registers for loops,
and might have restrictions not obvious today. In any case, the
restriction is there, and was enforced by some compilers for
constants, that otherwise didn't need to be restricted.




Juha Nieminen

unread,
Aug 29, 2022, 7:16:00 AM8/29/22
to
In comp.lang.c++ Lynn McGuire <lynnmc...@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).

Ron Shepard

unread,
Aug 29, 2022, 11:13:37 AM8/29/22
to
On 8/29/22 3:30 AM, Robin Vowels wrote:
> On Monday, August 29, 2022 at 5:07:13 PM UTC+10, Ron Shepard wrote:
[...]
>> The only justification I can see for this is that they wanted to be able
>> to implement the loop logic with unsigned integers.
> .
> Definitely not.
> The control variable at least would be an ordinary signed integer,
> because that variable could be used in integer and/or real
> expressions.

Yes, the index variable and all three variables m1, m2, and m3 are
fortran integers. There was no unsigned integer type in fortran then. or
now for that matter, so these variables were all regular fortran signed
integers.


> And if m2 and m3 are variables,, then for the same reason,
> these would be ordinary signed integers.
> .
>> Even then I don't know why zero was not allowed.

Yes, see above. Fortran did not have unsigned integers, then or now. But
as I said before, the only reason I can imagine for having that
limitation in the language is that they wanted to allow the processor to
implement the loop control logic using unsigned integers in whatever
instruction set the compiled code was running.

$.02 -Ron Shepard

Robin Vowels

unread,
Aug 29, 2022, 3:30:02 PM8/29/22
to
On Tuesday, August 30, 2022 at 1:13:37 AM UTC+10, Ron Shepard wrote:
> On 8/29/22 3:30 AM, Robin Vowels wrote:
> > On Monday, August 29, 2022 at 5:07:13 PM UTC+10, Ron Shepard wrote:
> [...]
> >> The only justification I can see for this is that they wanted to be able
> >> to implement the loop logic with unsigned integers.
> > .
> > Definitely not.
> > The control variable at least would be an ordinary signed integer,
> > because that variable could be used in integer and/or real
> > expressions.
> Yes, the index variable and all three variables m1, m2, and m3 are
> fortran integers. There was no unsigned integer type in fortran then. or
> now for that matter, so these variables were all regular fortran signed
> integers.
> > And if m2 and m3 are variables,, then for the same reason,
> > these would be ordinary signed integers.
> > .
> >> Even then I don't know why zero was not allowed..

> Yes, see above. Fortran did not have unsigned integers, then or now. But
> as I said before, the only reason I can imagine for having that
> limitation in the language is that they wanted to allow the processor to
> implement the loop control logic using unsigned integers in whatever
> instruction set the compiled code was running.
.
Some hardware used signed-magnitude form.
The arithmetic for incrementing the control variable
would have been implemented using whatever hardware was normally
used for integer arithmetic anywhere in the machine.
.
Similarly for comparing the loop control variable with m2.

gah4

unread,
Aug 30, 2022, 1:59:02 AM8/30/22
to
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.


Thomas Koenig

unread,
Aug 30, 2022, 1:18:08 PM8/30/22
to
Ron Shepard <nos...@nowhere.org> schrieb:
> On 8/28/22 9:28 AM, Charlie Roberts wrote:
> [...]
>> The authors of "Numerical Recipes" started out with F77 and so all the
>> code in their first book has arrays starting at 1. When they brought
>> out the C version, they resorted to just this trick!
>
> If I remember correctly, the code in the chapters was written in Pascal,
> and there was an appendix that had fortran code. Or maybe it was the
> other way around?

The first edition was released in 1986, for Fortran, see the
Wikipedia article.

> I don't remember what version of fortran they used, bu
> the book was published before there were any f77 compilers available,

This is not the case. I have a version of a manual for VS Fortran,
from February 1981, which describes a Fortran 77 compiler.

> so
> I'm guessing that it was f66+extensions. Then they wrote the f77 version
> a year or two later.

I have the first edition, it is definitely Fortran 77.

gah4

unread,
Aug 30, 2022, 3:15:13 PM8/30/22
to
On Tuesday, August 30, 2022 at 10:18:08 AM UTC-7, Thomas Koenig wrote:

(snip)

> This is not the case. I have a version of a manual for VS Fortran,
> from February 1981, which describes a Fortran 77 compiler.

WATFIV had most of the Fortran 77 features in 1973, but we
didn't know it at the time.

As well as I know, it was testing them out before the standard
was done. Much more fun at the time, though, than Fortran IV.
0 new messages