Hello,
i am trying to reduce some code by writing a generic routine for setting values to variables of different types, using a class(*) argument and performing select type on it. The following code works fine for fixed-length strings, but not for character(:), allocatable, which does not seem to get written at all in the routine.
program main
implicit none
character(:), allocatable :: alloc_str
character(len=20) :: fixed_str
call set_me( fixed_str )
write(*,*) fixed_str
call set_me( alloc_str )
write(*,*) allocated( alloc_str ), alloc_str
contains
subroutine set_me( val )
implicit none
class(*), intent(out) :: val
select type( val )
type is( character(*) )
val = "a string"
class default
write(*,*) "unknown type of val"
end select
end subroutine set_me
end program main
output:
a string
F
Is there some workaround for this, or a better way of doing it?
The goal would be to be able to accept and write both, the fixed-length and allocatable strings.
I thought of catching an error with checking if len_trim(val) is zero, which would indicate a non-allocated allocatable, but i can’t seem to find any info about the result of len_trim for a non-allocated string. Testing on gfortran gives zero, but is this true across all the different compilers? (analogous to size() of unallocated arrays being sometimes random)
You can pass an unallocated actual string argument to a dummy string argument that is not declared as allocatable, but then you can’t expect it to be allocated at all in the routine.
Ok, so if i understand correctly, for cases where i want to write a value to a variable, it is actually better to write separate routines because then i can manage the allocation in the routine; while for cases where i read a value from a variable i can use a generic routine with class(*) since the variable is surely already allocated.
It is invalid to pass an unallocated actual argument to a non-allocatable dummy argument.
I would caution against where you’re headed with this design. The call site knows the type. You’re making things more difficult by trying to make a single procedure re-determine the type.
Nope, unallocated and zero length/size are very different things. I.e. my bucket is empty vs I have no bucket. That goes for deferred length character variables as well as arrays.