2

I would like to create a derived type containing allocatable character array components. However, when I try to allocate memory in subroutines, nothing happens. It may be more clear with the code example below:

program test

  type t1
     character(len=:), allocatable :: c(:)
  end type t1

  type(t1) :: t

  call test_string1()
  call test_string2(t)

contains

  subroutine test_string1()
    character(len=:), allocatable :: c(:)

    allocate( character(10) :: c(1) )
    write(*, *) 'Size in string1: ', len(c)
  end subroutine test_string1


  subroutine test_string2(this)
    class(t1) :: this

    allocate( character(10) :: this%c(1) )
    write(*, *) 'Size in string2: ', len(this%c)
  end subroutine test_string2


end program test

I expect that the output of such a code would be:

 Size in string1:           10
 Size in string2:           10

However, what I actually get is the following:

 Size in string1:           10
 Size in string2:            0

Therefore, the second subroutine allocates nothing for the t1%c... What am I doing wrong here ? I have compiled the code with:

gfortran -c test.f08
gfortran -o test test.o

and the version of gfortran is the following:

$ gfortran -v
...
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
3
  • 3
    The only thing you are doing wrong is using a compiler with a bug! Appears to be fixed in gfortran 9. Commented Feb 11, 2020 at 10:53
  • Yup, I've just tried and that was it... Thanks for the tip ! Commented Feb 11, 2020 at 11:24
  • This code will be used to generate a command executed by 'execute_command_line', so I think the term "string" would have been more appropriate. Commented Feb 11, 2020 at 16:03

1 Answer 1

1

This is a bug (or lack of support) in the version of the compiler you are using. In gfortran versions 7 and 8 I see the same problem, but as noted, gfortran 9 gives the expected answer. "Use a different compiler/version" is an answer to your question.

What is sometimes helpful in cases like this is the additional question: "what can I do to work around this bug without changing compiler?"

The example of the question is fairly simple leading to not many options. Intrinsic assignment of a constructed array, or sourced allocation don't help.

Is there something interesting that does? Why, yes! Parameterized derived types.

It appears that gfortran 8 experiences the problem of the question but does support derived type parameterization (gfortran 7 doesn't support this Fortran 2003 feature). This could be a good work around, or even a good alternative approach to the real problem:

program test

  type t1(length, size)
     integer, len :: length, size
     character(len=length) :: c(size)
  end type t1

  class(t1(:,:)), allocatable :: t

  call test_string1()
  call test_string2(t)

contains

  subroutine test_string1()
    character(len=:), allocatable :: c(:)

    allocate( character(10) :: c(1) )
    write(*, *) 'Size in string1: ', len(c)
  end subroutine test_string1


  subroutine test_string2(this)
    class(t1(:,:)), allocatable :: this

    allocate( t1(10,1) :: this )
    write(*, *) 'Size in string2: ', len(this%c)
  end subroutine test_string2


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

1 Comment

Thanks for the insight, I didn't know about derived type parametrization ! In the project I am working on I am free concerning the choice of compilers, but this is something to know when distributing the program.

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.