The principles of pure procedures include no side effects, which is why the SAVE
attribute is prohibited. This definition is not specific to Fortran, per Pure function - Wikipedia. Writing to a file has a clear side-effects, both to the filesystem itself and to the system buffers used to implement file operations.
In any case, if folks want a non-conforming but practical workaround, use C. Fortran compilers cannot introspect C code and thus have no way to observe the violation, so this implementation is warning-free. It’s also possible to have the C function print_error
implemented as a no-op by default and then LD_PRELOAD
a shared-library containing the version with the debug output in it at runtime when necessary. In this case, the subroutine is PURE
except when debugging, which seems minimally evil.
// print_error.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ISO_Fortran_binding.h>
void print_error(int code, CFI_cdesc_t * message)
{
char * buffer = calloc(message -> elem_len + 1, 1);
memcpy(buffer, message -> base_addr, message -> elem_len);
printf("code=%d, message=%s\n", code, buffer);
}
! pure-error.F90
module m
interface
pure subroutine print_error(code, message) bind(C,name="print_error")
use iso_c_binding, only : c_int, c_char
implicit none
integer(c_int), intent(in), value :: code
character(kind=c_char), dimension(..), intent(in) :: message
end subroutine print_error
end interface
contains
pure subroutine f(i)
implicit none
integer, intent(in) :: i
if (i.eq.100) then
call print_error(i,"bad things have happened")
end if
end subroutine f
end module m
program main
use m
implicit none
integer :: i, n
n = 1000
do concurrent (i=1:n)
call f(i)
end do
end program main
% gcc-13 -I/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/current/gcc/aarch64-apple-darwin22/13/include -c print_error.c && gfortran-13 pure-error.F90 print_error.o && ./a.out
code=100, message=bad things have happened
My handling of strings of strings in this code may not be correct but that is not the important part of the example.