I have a legacy application with a commonly used trace function that I modified to take an optional argument, which temporarily replaces a trace message in the structure. The trace message in the structure has a fixed size. Here’s a simplified version:
type :: my_structure
character(128) :: trace_message
logical :: trace_enabled
end type
subroutine trace_execution(struct, message)
type(my_structure), intent(in) :: struct
character(*) , intent(in), optional :: message ! My addition
character(:), allocatable :: tmp
! Original function was outer if statement
if (struct%trace_enabled)
if (present(message)) then ! My addition
tmp = struct%trace_message
struct%trace_messgae = message
call my_trace_function(struct)
struct%trace_message = tmp
else
call my_trace_function(struct)
end if
end if
end subroutine
I originally declared the optional argument character(128), optional
like it is in the struct. Intel’s compiler didn’t like that because when I passed a literal (<128 characters in length) it said there’s a “character length mismatch” at the call site.
character(:), optional
didn’t work either: “a colon may be used as a type parameter value only in the declaration of an entity or component that has the POINTER or ALLOCATABLE attribute”
character(:), allocatable, optional
didn’t work either because the string literal wasn’t allocatable at the call site.
I want to avoid having a character(128)
variable at the call site, the whole point of this addition was supposed to be convenience .
My Question(s): So, is the function as written above the most correct? Should tmp
be declared the way it is? What about message
? What’s the difference between character(:)
and character(*)
?
Please keep in mind
- Assume I cannot change the structure itself (it interacts with third party software and needs to have a consistent layout)
- This function is called all over the place, so I don’t want to modify the procedure such that existing calls are impacted
Much appreciated!