fortrangfortranintel-fortrannag-fortranpgi-visual-fortran

Bound checking for empty arrays --- behavior of various compilers


Update 20210914: Absoft support confirms that the behavior of af95 / af90 described below is unintended and indeed a bug. Absoft developers will work to resolve it. The other compilers act correctly in this regard. Thank @Vladimir F for the answer, comments, and suggestions.


I have the impression that Fortran is cool with arrays of size 0. However, with Absoft Pro 21.0, I encountered a (strange) error involving such arrays. In contrast, gfortran, ifort, nagfor, pgfortran, sunf95, and g95 are all happy with the same piece of code.

Below is a minimal working example.

! testempty.f90

!!!!!! A module that offends AF90/AF95 !!!!!!!!!!!!!!!!!!!!!!!!
module empty_mod

implicit none
private
public :: foo

contains

subroutine foo(n)
implicit none
integer, intent(in) :: n
integer :: a(0)
integer :: b(n - 1)
call bar(a)  ! AF90/AF95 is happy with this line.
call bar(b)  ! AF90/AF95 is angry with this line.
end subroutine foo

subroutine bar(x)
implicit none
integer, intent(out) :: x(:)
x = 1  ! BAR(B) annoys AF90/AF95 regardless of this line.
end subroutine bar

end module empty_mod
!!!!!! Module ends !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


!!!!!! Main program !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program testempty

use empty_mod, only : foo

implicit none

call foo(2)  ! AF90/AF95 is happy with this line.
call foo(1)  ! AF90/AF95 is angry with this line.
write (*, *) 'Succeed!'  ! Declare victory when arriving here.

end program testempty
!!!!!! Main program ends !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Name this piece of code as testempty.f90. Then run

$ af95 -no-pie -et -Rb -g -O0 -o atest testempty.f90
$ ./atest

This is what happened on my machine (Ubuntu 20.04, linux 5.4.0-77-generic, x86_64):

./atest
? FORTRAN Runtime Error:
? Subscript 1 is out of range for dimension 1 for array 
? B with bounds 1:
? File testempty.f90; Line 19
? atest, run-time exception on Mon Sep 13 14:08:41 2021
? Program counter: 000000001004324B
? Signal SIGABRT, Abort
? Traceback follows
OBJECT             PC                ROUTINE                LINE  SOURCE
libpthread.so.0    000000001004324B  raise                   N/A  N/A
atest              00000000004141F3  __abs_f90rerr           N/A  N/A
atest              000000000041CA81  _BOUNDS_ERROR           N/A  N/A
atest              00000000004097B4  __FOO.in.EMPTY_MO       N/A  N/A
atest              000000000040993A  MAIN__                   40  testempty.f90
atest              000000000042A209  main                    N/A  N/A
libc.so.6          000000000FD0C0B3  __libc_start_main       N/A  N/A
atest              000000000040956E  _start                  N/A  N/A

So af95 was annoyed by call bar(b). With af90, the result was the same.

I tested the same code using gfortran, ifort, nagfor, pgfortran, sunf95, and g95. All of them were quite happy with the code even though I imposed bound checking explicitly. Below is the Makefile for the tests.

# This Makefile tests the following compilers on empty arrays.
#
# af95: Absoft 64-bit Pro Fortran 21.0.0
# gfortran: GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
# ifort: ifort (IFORT) 2021.2.0 20210228
# nagfor: NAG Fortran Compiler Release 7.0(Yurakucho) Build 7036
# pgfortran: pgfortran (aka nvfortran) 21.3-0 LLVM 64-bit x86-64
# sunf95: Oracle Developer Studio 12.6
# g95: G95 (GCC 4.0.3 (g95 0.94!) Jan 17 2013)
#
# Tested on Ubuntu 20.04 with Linux 5.4.0-77-generic x86_64

.PHONY: test clean

test:
    make -s gtest
    make -s itest
    make -s ntest
    make -s ptest
    make -s stest
    make -s 9test
    make -s atest

gtest: FC = gfortran -Wall -Wextra -fcheck=all
itest: FC = ifort -warn all -check all
ntest: FC = nagfor -C
ptest: FC = pgfortran -C -Mbounds
stest: FC = sunf95 -w3 -xcheck=%all -C
9test: FC = g95 -Wall -Wextra -fbounds-check
atest: FC = af95 -no-pie -et -Rb

%test: testempty.f90
    $(FC) -g -O0 -o $@ $<
    ./$@

clean:
    rm -f *.o *.mod *.dbg *test

Questions:

  1. Is the behavior of af95/af90 standard-conforming?
  2. Does my code contain anything that violates the Fortran standards?
  3. In general, is it considered dangerous to involve empty arrays in Fortran code? Sometimes they are inevitable given the fact the data sizes are often undecidable before runtime.

By "standards", I mean 2003, 2008, and 2018.

Thank you very much for any comments or criticism.

(The same question is posed on Fortran Discourse, and I hope it does not violate the rules here.)


Solution

  • The program looks OK to me. Zero-sized arrays are perfectly possible in Fortran although I admit I normally do not have automatic ones - but that is just a coincidence.

    I think it is a compiler bug in the Absoft compiler or its array bounds checker.