I am looking for a pure way to have access to time information. I thought about intrinsic functions and subroutines of standards compiler (date_and_time
,cpu_time
, system_clock
, ltime
, ctime
, ...), the format do not really matter to me. I also thought about MPI function, but it is the same as intrinsic functions, there are all impure functions.
Here is a minimal example:
elemental subroutine add(message, text)
! function add
IMPLICIT NONE
character(len=:),allocatable,intent(inout) :: message
character(len=*), intent(in) :: text
character(len=1), parameter :: nl=char(10)
character(10) :: time
! character(8) :: date
! time= 'hhmmss.sss'
call DATE_AND_TIME(time)
Message= Message//time////text//nl
end subroutine add
and I get a logical error :
Error: Subroutine call to intrinsic ‘date_and_time’ at (1) is not PURE
Thus, I am wandering if a pure way to have a time information exists, or if it is impossible to have it purely (maybe because it has to use cpu information which, for a reason unknown to me, could be thread-unsafe).
Maybe, a subquestion, could be is there a solution to force the compiler to consider date_and_time
pure (or any other function of that kind)?
The answer about a pure manner to get time is no. A function that returns the current time or date, is impure because at different times it will yield different results—it refers to some global state.
There are certainly tricks to persuade the compiler that a subroutine is pure. One is to flat out lie in an interface block.
But there are consequences from lying to the compiler. It can do optimizations which are unsafe to do and the results will be undefined (most often correct anyway, but...).
module m
contains
elemental subroutine add(text)
IMPLICIT NONE
character(len=*), intent(in) :: text
character(len=1), parameter :: nl=char(10)
character(10) :: time
intrinsic date_and_time
interface
pure subroutine my_date_and_time(time)
character(10), intent(out) :: time
end subroutine
end interface
call MY_DATE_AND_TIME(time)
end subroutine add
end module
program test
use m
call add("test")
end program
subroutine my_date_and_time(time)
character(10), intent(out) :: time
call date_and_time(time)
end subroutine
Notice I had to delete your message
because that was absolutely incompatible with elemental
.