• =?UTF-8?B?UmU6IOKAnFdoeSBkbyBhcnJheXMgc3RhcnQgYXQgMD8i?=

    From gah4@21:1/5 to Gary Scott on Fri Aug 26 18:24:05 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to d thiebaud on Fri Aug 26 19:34:46 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to d thiebaud on Fri Aug 26 20:34:24 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Lynn McGuire on Fri Aug 26 20:31:34 2022
    On Saturday, August 27, 2022 at 6:49:55 AM UTC+10, 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.
    .
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fiziqs@gmail.com@21:1/5 to Robin Vowels on Sat Aug 27 01:48:13 2022
    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).
    FORTRAN started at 1 for subscripts.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to fiz...@gmail.com on Sat Aug 27 02:17:58 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to fiz...@gmail.com on Sat Aug 27 05:16:35 2022
    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.
    .
    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).
    .
    FORTRAN started at 1 for subscripts.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Koenig on Sat Aug 27 10:01:01 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to d thiebaud on Sat Aug 27 12:45:25 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Fred. Zwarts@21:1/5 to All on Sat Aug 27 21:26:12 2022
    XPost: comp.lang.c++

    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John@21:1/5 to All on Sat Aug 27 19:34:27 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Keith Thompson on Sat Aug 27 23:04:14 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Koenig on Sat Aug 27 22:26:27 2022
    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."

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to John on Sun Aug 28 01:50:29 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Bonita Montero on Sun Aug 28 02:55:49 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Bonita Montero on Sun Aug 28 05:47:02 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to All on Sun Aug 28 13:42:22 2022
    On 8/28/2022 12:26 AM, gah4 wrote:
    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."

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

    DO 10 I = ncp, 1, -1

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Lynn McGuire on Sun Aug 28 14:05:06 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Koenig on Sun Aug 28 14:08:41 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to All on Sun Aug 28 21:54:48 2022
    On Monday, August 29, 2022 at 7:05:08 AM UTC+10, gah4 wrote:
    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.
    .
    You might have to wait a long time for that to happen.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Lynn McGuire on Sun Aug 28 21:53:31 2022
    On Monday, August 29, 2022 at 4:42:28 AM UTC+10, Lynn McGuire wrote:
    On 8/28/2022 12:26 AM, gah4 wrote:
    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."
    What ? Our code has negative indexes dating back to F66 days. I am
    assuming that this is:

    DO 10 I = ncp, 1, -1
    .
    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).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Thomas Koenig on Mon Aug 29 02:07:08 2022
    On 8/27/22 5:13 PM, Thomas Koenig wrote:
    gah4 <gah4@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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Charlie Roberts on Mon Aug 29 02:42:30 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Ron Shepard on Mon Aug 29 01:30:29 2022
    On Monday, August 29, 2022 at 5:07:13 PM UTC+10, Ron Shepard wrote:
    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.
    .
    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.
    .
    Even then I don't know why zero was not allowed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Ron Shepard on Mon Aug 29 03:48:43 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Robin Vowels on Mon Aug 29 10:13:32 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Ron Shepard on Mon Aug 29 12:30:00 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Koenig on Tue Aug 30 12:15:11 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)