https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118735
Bug ID: 118735 Summary: gfortran not following deferred initialization rules for get_command_argument Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: andi.m.mcclure at gmail dot com Target Milestone: --- Created attachment 60366 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60366&action=edit File from first github link above I believe I have found a nonconformance with gfortran 14.2.0 targeting the 2023 standard. * 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 The GNU docs' recommended usage of this function is to preallocate a character array longer than the possible maximum and then trim. 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 2023 draft spec states in GET_COMMAND_ARGUMENT that "value" is indeed INTENT(OUT). If this spec section applied to GET_COMMAND_ARGUMENT it would be much preferable because it would mean arguments of any length could be easily taken, useful e.g. for long paths. However, in my testing automatic allocation of the GET_COMMAND_ARGUMENT out value does *not* work 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 (my 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, followed by > 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 and a workaround; this 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 flawlessly (and you can confirm it actually is opening the file by passing the name of a non-existent file as argument, which the program will then create (because`action='read'` is not specified in the open())): 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. I ran this by the GNU fortran mailing list and was told to file here. * Configuration I am using Debian Trixie on AMD64, I and installed gfortran from apt. $ gfortran -v Using built-in specs. COLLECT_GCC=gfortran COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/14/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 14.2.0-12' --with-bugurl=file:///usr/share/doc/gcc-14/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust --prefix=/usr --with-gcc-major-version-only --program-suffix=-14 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-14-14.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-14-14.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=3 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.2.0 (Debian 14.2.0-12) Note: I have no pressing personal need for a fix for this, and my FORTRAN project is now complete.