I have a character string I would like to initialize with intent(out) data from a subroutine call. I kind of looks like that:
character(*) :: path
call get_path(path)
The compiler tells me:
Error: Entity with assumed character length at (1) must be a dummy argument or a PARAMETER
The construct works just fine in a subroutine but fails in the main program. Is it possible to initialize the path variable without knowing its length?
EDIT: Stuff I already tried but failed.
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(path(len(trim(path_temp))))
Error: Shape specification for allocatable scalar at (1)
I don't get why the compiler thinks path is a scalar.
A function that returns a character with assumed length apparently is illegal.
character(*) function get_path ()
get_path = '/path/to/folder/'
end function get_path
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
What works but gives me a headache because I find it very bad style is to give path an insane length and trim it every time it's used. I think my compiler is having trouble with allocatable character strings because it isn't quite up to date (mpif90). Not sure if it supports them.
len will give you the length of the string including trailing blanks. If you want the length excluding trailing blanks, then use len_trim .
Many of the points are covered in other answers linked by comments, such as what "assumed length" requires and how to allocate the scalar deferred length character variable.
I'll point out two things, before coming to an particular answer.
Intrinsic assignment to a deferred length allocatable scalar character variable results in (if required) allocation of that variable to the length of the expression. That is
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(character(len(trim(path_temp))) :: path) ! Note the correct form
path = TRIM(path_temp) ! Or path(:)=path_temp
can be replaced by
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
path = TRIM(path_temp)
The other thing to note is quite pedantic, but using the terminology incorrectly may hinder searching. Initialization in Fortran means something specific which isn't applicable here.
You say that a function with an assumed length character result is apparently illegal, based on the compiler error message
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
That isn't entirely true: character function results can (currently - it's an obsolescent feature of modern Fortran) be of assumed length in some circumstances. They must, though, be external functions. See that the compiler complains about a module procedure (which then isn't external).
That said, having an assumed length character result doesn't help you. The length of the result still has to be assumed from something, and that something isn't in the function body, but a declaration that defines the external function in a scope.
Something like
implicit none
character(99) get_path ! The length of the get_path result is assumed from here
character(:), allocatable :: path
path = TRIM(get_path())
...
As you seem to have complete control over the subroutine get_path
, there's the final answer-worthy comment to make. You could directly have the argument allocatable.
subroutine get_path(path)
character(:), allocatable, intent(out) :: path
path = '/path/to/folder/' ! Allocation through intrinsic assignment
path = TRIM(path) ! In general, if it's likely to have trailing blanks
end subroutine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With