This last week, as an exercise in learning FORTRAN, I attempted to complete
a programming puzzle ( https://adventofcode.com/2024/day/4 ) with gfortran.
I made a specific decision to target the 2023 standard and *not* the GNU
standard.

I believe I have found a nonconformance with gfortran 14.2.0 targeting the
2023 standard(1).

Details: I wanted my program to input data from a file, and intended it to
take the filename from the command line. I found the standard way to do
this is:

https://gcc.gnu.org/onlinedocs/gfortran/GET_005fCOMMAND_005fARGUMENT.html

Normal usage of this function involves knowing the length of the argument
you are going to input ahead of time(2). However, I had been reading
standards documents, and found this section in this 2023 "informal"
publication of the Fortran working group, "The new features of Fortran
2023" https://wg5-fortran.org/N2201-N2250/N2212.pdf , emphasis mine:

> 2.2 US 14. Automatic allocation of lengths of character variables
> When a deferred-length allocatable variable is defined by intrinsic
assignment, as in the example
>
>     character(:), allocatable :: quotation
>     :
>     quotation = ’Now is the winter of our discontent.’
>
> it is allocated by the processor to the correct length. This behaviour is
extended to messages
> returned through iomsg and errmsg specifiers, writing to a scalar
character variable as an
> internal file, and intent out and inout scalar character arguments of
intrinsic procedures, **such
> as in call `get_command(command)`**.

This is an informal publication but I believe this should be taken to apply
to the "value" argument of GET_COMMAND_ARGUMENT, for three reasons: Because
the "new features" document explicitly calls out GET_COMMAND, and
GET_COMMAND_ARGUMENT is so similar; because the 2023 draft standard I find
https://j3-fortran.org/doc/year/23/23-007r1.pdf seems to confirm the
behavior, in 16.9.1: "When an allocatable deferred-length character scalar
corresponding to an INTENT (INOUT) or INTENT (OUT) argument is assigned a
value, the value is assigned as if by intrinsic assignment."; and because
the same draft spec states in GET_COMMAND_ARGUMENT that "value" is indeed
INTENT(OUT).

However, I do *not* see automatic allocation of the GET_COMMAND_ARGUMENT
out value in gfortran. Here is a test program:

https://github.com/mcclure/aoc2024/blob/822e460f81b944c21ca675303b868c45b22a4c2b/04-01-wordsearch/src/puzzle.f90

I run this with `gfortran src/puzzle.f90 -std=f2023 -o program && ./program
data/puzzle.txt`. This program defines a character string as in the FORTRAN
2023 "new features" document (the source says "len=:" rather than ":", but
changing this to ":" does not change the output), passes the unallocated
string to GET_COMMAND_ARGUMENT, prints the string, then attempts to open a
file by that name. When print, the string appears to be empty; a blank line
is printed, and then

> At line 20 of file src/puzzle.f90 (unit = 10)
> Fortran runtime error: Cannot open file '': No such file or directory

Here's a longer test program, with a long comment, which passes the string
to GET_COMMAND_ARGUMENT but also a variable for the "length" out parameter.
It then allocates a string of that length and passes it to
GET_COMMAND_ARGUMENT. This works (and you can confirm it is opening the
file by passing the name of a non-existent file as argument, which the
program will then create(3)):

https://github.com/mcclure/aoc2024/blob/b31be91adb5a0721f97e2ba8f145da4f36129753/04-01-wordsearch/src/puzzle.f90

Summary: It is my opinion from the FORTRAN 2023 spec that the first test
program above should have worked and the additional steps in the second
test program should not have been necessary. Have I misread the spec, is
there something wrong with my code, or have I identified a bug in gfortran?
Should I file at the GCC Bugzilla?

---

(1) If I'm not mistaken 14.2.0 dates from August 2024, so I would expect it
to be up to date. I installed gfortran via Debian Trixie and here is the
output of gfortran -v:
https://gist.githubusercontent.com/mcclure/9ccf6010b2db4b19adbed3127192c9da/raw/9fb74f44124a727a5d88730f2d69ffb4b2bca6f2/gfortran.txt

(2) The sample code in the GNU doc recommends allocating a string longer
than needed, in which excess space will be filled with blanks. This
solution was in practice adequate for my needs, but because my goal in
writing the program was to learn modern FORTRAN, I decided to try to "do it
right" if possible.

(3) The sample is minimal, so `action='read'` is not specified in the
open() call.

Reply via email to