Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic allocation of string arrays in Fortran does not resize

Consider the following Fortran program:

program test
character(len=:), allocatable :: str
allocate(character(3) :: str)
print *, len(str)
str = '12345'
print *, len(str)
end program

When I run this I get the expected result:

   3
   5

That is, the character string was resized from 3 to 5 when str was set to '12345'. If, instead, I use an array of dynamic strings this is not true. Example:

program test
character(len=:), allocatable :: str(:)
allocate(character(3) :: str(2))
print *, len(str(1)), len(str(2))
str(1) = '12345'
print *, len(str(1)), len(str(2))
end program

When I run this I get:

   3           3
   3           3

So the set of str(1) did not change the length the string. I get the same behavior with ifort 16.0.2 and gfortran 5.3.1. My question is this behavior consistent with the latest Fortran standard or is this a bug in the compilers?

like image 774
DavidS Avatar asked May 09 '18 14:05

DavidS


People also ask

What does Allocatable mean in Fortran?

The ALLOCATABLE attribute allows you to declare an allocatable object. You can dynamically allocate the storage space of these objects by executing an ALLOCATE statement or by a derived-type assignment statement. If the object is an array, it is a deferred-shape array or an assumed-rank array.


2 Answers

This is the correct behaviour. An element of an allocatable array is not itself an allocatable variable and cannot be re-allocated on assignment (or in any other way). Also, all array elements must have the same type - including the string length.

like image 148
Vladimir F Героям слава Avatar answered Nov 15 '22 04:11

Vladimir F Героям слава


Expanding on @Vladimir F's answer, you could achieve what you have in mind with a few changes to your code, like the following (which creates a jagged array of character vectors):

program test

type :: CherVec_type
    character(len=:), allocatable :: str
end type CherVec_type

type(CherVec_type) :: JaggedArray(2)

allocate(character(3) :: JaggedArray(1)%str)
allocate(character(3) :: JaggedArray(2)%str)
print *, len(JaggedArray(1)%str), len(JaggedArray(2)%str)

JaggedArray(1)%str = "12345"
print *, len(JaggedArray(1)%str), len(JaggedArray(2)%str)

end program

which creates the following output:

$gfortran -std=f2008 *.f95 -o main
$main
       3           3
       5           3
like image 30
Scientist Avatar answered Nov 15 '22 02:11

Scientist