Using Iso_Fortran_Env to set a function's Kind

2019-08-02 10:14发布

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()

3条回答
小情绪 Triste *
2楼-- · 2019-08-02 10:28

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
查看更多
Viruses.
3楼-- · 2019-08-02 10:37

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.

查看更多
神经病院院长
4楼-- · 2019-08-02 10:43

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
查看更多
登录 后发表回答