I need to return an an array of strings from a subroutine in fortran, the length of which is supposed to be determined at runtime. The solution I have found, which works with intel fortran, crashes with gfortran however.
Example Code
The following code seems to work with Intel Fortran (15.0.3), but fails with a segmentation fault with gfortran 5.3.0:
program stringtest ! filename:str2.f08
implicit none
integer n
character(len=:), allocatable :: y(:)
write(*,*) 'mkchars...'
call mkchars(y)
write(*,*) 'mkchars... Done.'
write(*,'(5("|",A,"|"))') y
contains
subroutine mkchars(oc)
character(len=:), allocatable, intent(out) :: oc(:)
allocate(character(len=8) :: oc(5))
write(*,*) 'shape ', shape(oc)
write(*,*) 'length ', (len(oc(n)), n=1,5)
write(*,*) 'storage', storage_size(oc)
oc(1) = "Hello"
oc(2) = "World" ! <-------------------- crashes here with gfortran
oc(3) = "how"
oc(4) = "are"
oc(5) = "you?"
end subroutine mkchars
end program stringtest
IFort output
With Intel Fortran 15.0.3, this produces
mkchars...
shape 5
length 8 8 8 8 8
storage 64
mkchars... Done.
|Hello ||World ||how ||are ||you? |
GFortran: Executable Crashes upon assignment to OC(2)
With gfortran, however, I get a segmentation fault when assigning to OC(2), even though the shape of the array and the length of each entry are reported as expected:
C:\tmp>gdb -batch -ex run -ex bt a.exe
[New Thread 12024.0x38e4]
mkchars...
shape 5
length 8 8 8 8 8
storage 64
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401840 in mkchars (oc=<incomplete type>, _oc=_oc@entry=0x61fdbc) at c:/tmp/str2.f08:20
20 oc(2) = "World"
#0 0x0000000000401840 in mkchars (oc=<incomplete type>, _oc=_oc@entry=0x61fdbc) at c:/tmp/str2.f08:20
#1 0x00000000004019a0 in stringtest () at c:/tmp/str2.f08:9
#2 0x0000000000401a84 in main (argc=1, argv=0x6f5890) at c:/tmp/str2.f08:9
#3 0x00000000004013e8 in __tmainCRTStartup ()
#4 0x000000000040151b in mainCRTStartup ()
Am I doing something wrong, or is this a possible compiler bug?
Is there some other method of returning allocated string-arrays from subroutines that works in gfortran?
For the actual use-case at hand, I can fall back to using an oversized fixed-size array (roughly 100KB instead of <1KB) and ignoring the unused parts. I would however prefer a cleaner solution.