• Can a scalar variable appear more than once as a READ input item?

    From Beliavsky@21:1/5 to All on Tue Mar 29 18:19:44 2022
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    so I think

    read (text,*) j(1),j(1)

    is non-standard. What about reading a scalar twice, as in

    read (text,*) i,i

    The reason to read a variable more than once is to skip over data.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Beliavsky on Tue Mar 29 22:31:21 2022
    On Tuesday, March 29, 2022 at 6:19:46 PM UTC-7, Beliavsky wrote:
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    In the case of C and the C standard, there are many cases of "undefined behavior".

    If a program does something the is UB, one is not supposed to have any expectations
    about the results. Anything can happen. (Including what you most hope happens.)

    There is also Implementation defined behavior. In this case, there are normally
    a small number of things that can happen, which only apply to the specific part in question.

    In the case of UB, in the given case, you would not have any expectation about the results of the program. In the case of IDB, only the specific variables in question would be questioned.

    In the latter case, you would not know the value of the specific variables listed
    more than once, but other variables would be fine.

    Note, for example, recent discussion on the END= or ERR= exit, which can occur during execution of a READ statement, such that all variables listed should be considered undefined. It would be nice to believe that earlier variables are fine,
    and only later (not yet read) undefined, but the standard doesn't say that.

    I suspect that you have to read the standard more carefully to understand this case.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Beliavsky on Wed Mar 30 00:48:08 2022
    On 3/29/22 8:19 PM, Beliavsky wrote:
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    I was not aware of this restriction. I checked the standard, and the restriction is there, so MRC is correct. The example given in the
    standard is an array referenced with a vector subscript, not with
    literal constants, but I do not see any exception for that latter case.

    so I think

    read (text,*) j(1),j(1)

    is non-standard. What about reading a scalar twice, as in

    read (text,*) i,i

    The reason to read a variable more than once is to skip over data.

    I do not see a similar restriction on repeated scalar variables in the
    i/o list. I certainly see this done in practice for the reason you give,
    to skip over items in the file and to ignore their values.

    $.02 -Ron Shepard

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Beliavsky on Tue Mar 29 22:58:38 2022
    On Wednesday, March 30, 2022 at 12:19:46 PM UTC+11, Beliavsky wrote:
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    so I think

    read (text,*) j(1),j(1)

    In this example, the first J(1) is one input item. It does not contain another reference to J.
    The second J(1) is another (separate) input item. It also does not contain another reference to J.
    The READ statement is therefore legal.

    is non-standard. What about reading a scalar twice, as in

    read (text,*) i,i

    The reason to read a variable more than once is to skip over data.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to Beliavsky on Wed Mar 30 06:13:03 2022
    Beliavsky <beliavsky@aol.com> schrieb:
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."


    so I think

    read (text,*) j(1),j(1)

    is non-standard.

    I don't think that is the case. F2018:

    R1216 input-item is variable
    or io-implied-do

    so j(1) and j(1) are two separate input items, and the code is fine.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to gah4@u.washington.edu on Wed Mar 30 06:26:45 2022
    gah4 <gah4@u.washington.edu> schrieb:
    On Tuesday, March 29, 2022 at 10:48:12 PM UTC-7, Ron Shepard wrote:
    On 3/29/22 8:19 PM, Beliavsky wrote:

    (snip)

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    I was not aware of this restriction. I checked the standard, and the
    restriction is there, so MRC is correct. The example given in the
    standard is an array referenced with a vector subscript, not with
    literal constants, but I do not see any exception for that latter case.

    Yes, I also found the restriction.

    Note that the restriction is on an item, not an item list.

    To expand on what I wrote earlier, this means that

    read (10,*) a(1), a(1)

    is fine, but

    read (10,*) a([1,1])

    or

    read (10,*) (a(i/2),i=1,10)

    or

    read (10,*) (a(i),a(i),i=1,10)

    is not.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Thomas Koenig on Tue Mar 29 23:27:14 2022
    On Tuesday, March 29, 2022 at 11:13:06 PM UTC-7, Thomas Koenig wrote:

    (snip)

    I don't think that is the case. F2018:

    R1216 input-item is variable
    or io-implied-do

    so j(1) and j(1) are two separate input items, and the code is fine.

    Oh, so:

    READ(1) (X(1), X(1), I=1,N)

    would not be allowed, to ignore 2*N items.

    But also:

    READ(1) (X(I/2), I=2,10)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to Ron Shepard on Tue Mar 29 23:23:46 2022
    On Tuesday, March 29, 2022 at 10:48:12 PM UTC-7, Ron Shepard wrote:
    On 3/29/22 8:19 PM, Beliavsky wrote:

    (snip)

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    I was not aware of this restriction. I checked the standard, and the restriction is there, so MRC is correct. The example given in the
    standard is an array referenced with a vector subscript, not with
    literal constants, but I do not see any exception for that latter case.

    Yes, I also found the restriction.

    Note that there are a number of different ways to use array element that
    can complicate I/O. Note, for example, (though I haven't looked recently)
    to do something like:

    READ(1) N, (X(I), Y(I), I=1,N)

    Input items can be used in later items in the I/O list. I believe there is
    a restriction on things like:

    READ(1) (X(I), I=1,X(3))

    where an input item is otherwise used in the same implied-DO group.
    Now you get to things like:

    READ(1) I, X(I), J, X(J)

    which we know is legal when the read-in I is different from the read-in J.
    The discussed restriction suggests that it isn't if I equals J, even
    though it doesn't look so much harder to process.

    (snip)

    is non-standard. What about reading a scalar twice, as in

    read (text,*) i,i

    The reason to read a variable more than once is to skip over data.

    I do not see a similar restriction on repeated scalar variables in the
    i/o list. I certainly see this done in practice for the reason you give,
    to skip over items in the file and to ignore their values.

    Note that the standard also doesn't say what the result should be.

    By the way, C has a way to skip items in formatted input, with a *.

    You can say, for example:

    scanf("%*f");

    such that it will read, and ignore, one f format item, following the normal rules
    for f format, except for storing the data. This can be part of a larger list:

    scanf("%f%*f%f", &x, &z);

    Since C format items don't have the fixed width that Fortran items do,
    it isn't so easy to ignore by length. Using, for example, 9X would traditionally
    be used to ignore some columns, but that doesn't work for UNFORMATTED.

    But as your example shows, in the case of list directed, you do need a way
    to ignore something.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Beliavsky@21:1/5 to Thomas Koenig on Wed Mar 30 04:01:54 2022
    On Wednesday, March 30, 2022 at 2:26:48 AM UTC-4, Thomas Koenig wrote:
    Note that the restriction is on an item, not an item list.

    To expand on what I wrote earlier, this means that

    read (10,*) a(1), a(1)

    is fine, but

    read (10,*) a([1,1])

    or

    read (10,*) (a(i/2),i=1,10)

    or

    read (10,*) (a(i),a(i),i=1,10)

    is not.

    Thanks. That explains why for the code

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1),k(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    read (text,*) k([1,1])
    print*,"i=",i
    print*,"j=",j
    print*,"k=",k
    end program main

    gfortran complains only about one of the lines, saying

    read_items.f90:8:17-19:

    8 | read (text,*) k([1,1])
    | 1 2
    Error: Elements with the same value at (1) and (2) in vector subscript in a variable definition context (item in READ)

    ifort, flang, and g95 do not say anything and give output

    i= 4
    j= 4
    k= 4

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to All on Wed Mar 30 03:54:07 2022
    On Wednesday, March 30, 2022 at 5:23:47 PM UTC+11, gah4 wrote:
    On Tuesday, March 29, 2022 at 10:48:12 PM UTC-7, Ron Shepard wrote:
    On 3/29/22 8:19 PM, Beliavsky wrote:
    (snip)
    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    I was not aware of this restriction. I checked the standard, and the restriction is there, so MRC is correct. The example given in the
    standard is an array referenced with a vector subscript, not with
    literal constants, but I do not see any exception for that latter case.
    Yes, I also found the restriction.

    Note that there are a number of different ways to use array element that
    can complicate I/O. Note, for example, (though I haven't looked recently)
    to do something like:

    READ(1) N, (X(I), Y(I), I=1,N)

    Input items can be used in later items in the I/O list. I believe there is
    a restriction on things like:

    READ(1) (X(I), I=1,X(3))

    where an input item is otherwise used in the same implied-DO group.
    Now you get to things like:

    READ(1) I, X(I), J, X(J)

    which we know is legal when the read-in I is different from the read-in J. The discussed restriction suggests that it isn't if I equals J, even
    though it doesn't look so much harder to process.

    This is legal. See earlier discussion.
    X(J) is an element, and contains only one reference to X(J).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to Thomas Koenig on Wed Mar 30 12:41:37 2022
    On 3/30/22 1:26 AM, Thomas Koenig wrote:
    gah4 <gah4@u.washington.edu> schrieb:
    On Tuesday, March 29, 2022 at 10:48:12 PM UTC-7, Ron Shepard wrote:
    On 3/29/22 8:19 PM, Beliavsky wrote:

    (snip)

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    I was not aware of this restriction. I checked the standard, and the
    restriction is there, so MRC is correct. The example given in the
    standard is an array referenced with a vector subscript, not with
    literal constants, but I do not see any exception for that latter case.

    Yes, I also found the restriction.

    Note that the restriction is on an item, not an item list.

    To expand on what I wrote earlier, this means that

    read (10,*) a(1), a(1)

    is fine, but

    read (10,*) a([1,1])

    or

    read (10,*) (a(i/2),i=1,10)

    or

    read (10,*) (a(i),a(i),i=1,10)

    is not.

    Hmmm, this is even more complicated that I thought at first.

    $.02 -Ron Shepard

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ron Shepard@21:1/5 to All on Wed Mar 30 12:34:29 2022
    On 3/30/22 12:31 AM, gah4 wrote:
    On Tuesday, March 29, 2022 at 6:19:46 PM UTC-7, Beliavsky wrote:
    [...]
    Note, for example, recent discussion on the END= or ERR= exit, which can occur
    during execution of a READ statement, such that all variables listed should be
    considered undefined. It would be nice to believe that earlier variables are fine,
    and only later (not yet read) undefined, but the standard doesn't say that.

    I think the reason dates back to the characteristics of the first hard
    disks. A READ statement might require data from multiple sectors on the
    disk, or for multiplatter disks, even data from multiple surfaces within
    a cylinder. When the READ statement is processed, the entire layout on
    the disk for all the data was determined. Then the data transfer was coordinated with the current location of the spinning disk (which was
    slow) so that the first available sectors were read first and where the
    head movement (which was very slow) was minimized. The variables in the
    i/o list could thereby be filled in almost arbitrary order, and if the
    same read statement were executed multiple times, they could be filled
    in a different orders each time, depending on the positions of the
    spinning disk and of the head at the moment of the READ statement.

    The example in this thread did not involve disk i/o, it was an internal
    READ, so none of that applies. But I think the overall semantics of the
    READ statement probably derive from that history.

    $.02 -Ron Shepard

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lynn McGuire@21:1/5 to Beliavsky on Wed Mar 30 12:43:48 2022
    On 3/29/2022 8:19 PM, Beliavsky wrote:
    The program

    program main
    implicit none
    character (len=100) :: text
    integer :: i,j(1)
    text = "2 4"
    read (text,*) i,i
    read (text,*) j(1),j(1)
    print*,"i=",i
    print*,"j=",j
    end program main

    gives output

    i= 4
    j= 4

    with gfortran and Intel Fortran. Section 10.4 of Metcalf/Reid/Cohen (2018) says

    "However, no element of the array may appear more than once in an input item."

    so I think

    read (text,*) j(1),j(1)

    is non-standard. What about reading a scalar twice, as in

    read (text,*) i,i

    The reason to read a variable more than once is to skip over data.

    Yes, we do it all the time.

    Lynn

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John Collins@21:1/5 to All on Fri Apr 1 11:12:12 2022
    "However, no element of the array may appear more than once in an input item."

    There must have been a reason for this restriction, and the fact that it doesn't apply to scalars. I am not happy with @Ron Shepard's suggestion that the IO list items could be filled in any order because you can read a value and then use the value to
    control subsequent reads in the same statement, e.g.

    READ(*,*)i,(a(j),j=1,i)

    Does anyone know the reason? How long has this been in the standard?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to john.c...@simconglobal.com on Fri Apr 1 23:24:22 2022
    On Friday, April 1, 2022 at 11:12:14 AM UTC-7, john.c...@simconglobal.com wrote:
    "However, no element of the array may appear more than once in an input item."
    There must have been a reason for this restriction, and the fact that it doesn't apply to scalars.

    The compiler can recognize at compile time when the same scalar is used.
    With variable subscripts, it is harder for the compiler.

    Often, though, my feeling is that there doesn't need to be a reason for a restriction,
    but a reason to remove one.

    Restrictions are added when someone thinks that it might be harder
    for compilers to figure out, but not actually know that.

    My thoughts about PL/I is that they added features without worry about
    the complications for compiler writers. Simple rules make it easier for
    users, but also allow interesting things.

    With ENTRY in functions, Fortran EQUIVALENCEs all the return values.
    PL/I does the appropriate conversion. That might mean lots of conversion routines that would never be called, but it makes more sense for users.

    The only complication with array elements is the possibility of
    them being assigned in a different order than expected.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to All on Sat Apr 2 02:50:28 2022
    On Saturday, April 2, 2022 at 5:24:24 PM UTC+11, gah4 wrote:
    On Friday, April 1, 2022 at 11:12:14 AM UTC-7, john.c...@simconglobal.com wrote:
    "However, no element of the array may appear more than once in an input item."
    There must have been a reason for this restriction, and the fact that it doesn't apply to scalars.
    The compiler can recognize at compile time when the same scalar is used.
    With variable subscripts, it is harder for the compiler.

    Often, though, my feeling is that there doesn't need to be a reason for a restriction,
    but a reason to remove one.

    Restrictions are added when someone thinks that it might be harder
    for compilers to figure out, but not actually know that.

    My thoughts about PL/I is that they added features without worry about
    the complications for compiler writers. Simple rules make it easier for users, but also allow interesting things.
    .
    Some thought would have been given to implementation issues,
    but in the main, the design of PL/I was to remove many of the silly and
    irksome restrictions that existed in FORTRAN, and to make it easier
    for the programmer to implement an algorithm.
    .
    For example, there were silly restrictions on what could be a subscript
    in FORTRAN. In generalising that in PL/I, it was possible to use a
    common routine to validate an expression and to produce the object
    code (instead of a separate piece of code to syntax-check a limited
    expression and to produce object code for that).
    .
    In PL/I, it is possible for a DO statement for a loop to have
    multiple specifications for iteration. These would have been
    more difficult to implement compared to a single specification.
    Yet it provided greater facility to the programmer.
    For example, the cocktail-shaker sort usually contains two
    separate loops: one to examine elements from the first to last,
    and another from last to first.
    .
    These can be handled by a single DO statement:

    DO I = 1 TO N-1, N-1 TO 1 BY -1;
    ...
    END;
    which yields in a simpler algorithm.
    .
    With ENTRY in functions, Fortran EQUIVALENCEs all the return values.
    PL/I does the appropriate conversion. That might mean lots of conversion routines that would never be called, but it makes more sense for users.
    .
    That was useful in the old days, with small memories. I doubt that much
    use of that is made now.
    .
    The only complication with array elements is the possibility of
    them being assigned in a different order than expected.

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