3

I am trying to use a variable length string to read some data from NetCDF. In order to use the NetCDF calls I must provide a string large enough to accommodate the data. But I am running into problems.

I stripped down the problem in a weird behavior of the gfortran compiler. At least I think it is so, but maybe it is a Fortran 90 feature.

Here is the sample code:

    program test
    implicit none

    integer clen,slen
    character(len=:), allocatable :: string

    clen = 10
    allocate(character(len=clen) :: string)
    slen = len(string)

    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = ' '
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = 'test'
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)

    end

I would expect to get for all three write statements "10 10 10", since the string I have allocated is of size 10.

However, here is what I get:

clen,slen,dlen:           10          10          10
clen,slen,dlen:           10          10           1
clen,slen,dlen:           10          10           4

It seems as if string gets reallocated every time I assign to it. This is not the behavior I expect.

I probably use an outdated version of gfortran (GNU Fortran (Debian 4.9.2-10) 4.9.2). My question is: will this behavior go away with a newer version of the compiler, or is this a feature of Fortran 90? And if this is a feature, how can I avoid it?

1
  • Your code is not Fortran 90 compatible, but Fortran 2003. Fortran 90 is very old and obsolete, it is year 2017! Commented Dec 3, 2017 at 20:42

1 Answer 1

2

It seems as if string gets reallocated every time I assign to it.

This is exactly the case. I'll note first that your code isn't Fortran 90 compatible: so-called deferred length character variables were introduced in Fortran 2003.

When a deferred length character variable is the subject of intrinsic assignment (which is what you have here with string=...) it takes on the length of the expression on the right-hand side. This is similar to the behaviour with allocatable arrays.

After the allocate statement string is of length 10, but come

string = ' '

the right-hand side expression is of length 1 (a single blank). This means that string is deallocated and then reallocated to this new length.

Similarly to arrays, you can retain the length of the left-hand side in an assignment by using a substring:

string(:) = ' '

Such a substring is not subject to reallocation and you'll see the usual rules of fixed-length string assignment (padding or truncation of the right-hand side).

As a final comment, this reallocation is the case for assignment. When you pass string to a NetCDF procedure which populates the string it won't do such reallocation: the NetCDF procedures will consider the dummy argument as not being of deferred length. Your tests with intrinsic assignment aren't indicative of wider behaviour.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.