How would one go about using ISO Fortran Env's intrinsic to set a function's return KIND value in a manner which is idiomatic to Fortran 2008?
Normally within the main program, I can just use the ISO Fortran intrinsics as follows:
program name here
use iso_fortran_env
implicit none
integer, parameter :: double=REAL64
real(kind=double) :: some_variable
end program name here
But there doesn't seem to be a convenient way to use these intrinsics for external functions, since REAL64 and double would both be defined only within the main function above. Attempting to define the function's KIND within main as follows:
program name here
use iso_fortran_env
implicit none
integer, parameter :: double=REAL64
real(kind=double) :: some_function
! Do stuff
end program name here
real function some_function()
! Do stuff
end some_function
At least on my system, throws a type mismatch error (double gets defined as KIND=8, and a default real gets defined as a KIND=4 on my system). I could always just use real(kind=8) function some_function()
, but I'd prefer not to in the interest of portability. Plus, it just feels dirty to use REAL64 from iso_fortran_env in one place, only to turn around and use KIND=8 in another place.
Is there an easy (or at least, readable) way to accomplish that, such as below?
real(kind=REAL64) function some_function()
You start your question offers a solution at the and that solutions works well. As IanH points out there is some ambiguity in the standard wording, but I read it as saying it is allowed and compilers do accept this syntax:
fundef.f90:
real(kind=REAL64) function some_function()
use iso_fortran_env
some_function = 1._real64
end
compile:
> gfortran -c funkind.f90
>
You can use the kind defined in a module used inside the function. Tested also with Intel Fortran and Oracle Studio.
In modern Fortran all functions should be defined in a module anyway, but if you wish to you a kind from a module used only inside the function, the possibility is here.
Extending @chw21 's answer:
You always have the option to declare the type of a function result in the specification part of the function, and access parameters from modules by host association inside there.
Edit: «As pointed by @Vladimir F, you can also access variables by host association from a module declared inside the function body.»
In fact, this is the only way to apply attributes to the function result, like pointer, allocatable, dimension etc.
Moreover, you can also declare a new name for the function result through the result
suffix.
pure function some_other_function_with_a_long_name() result(out)
use, intrinsic :: iso_fortran_env, only: rk => real64
implicit none
real(rk), dimension(5) :: out
out = 1.0_rk
! (...)
end
I usually try it before posting, but I think this should work:
function some_function()
use iso_fortran_env, only: real64
implicit none
real(kind=real64) :: some_function
some_function = 1.0_real64
end function some_function
Or inside a module
module some_module
use iso_fortran_env, only: real64
implicit none
contains
real(kind=real64) function some_function()
some_function=1.0_real64
end function some_function
end module some_module