Использование Iso_Fortran_Env для установки значения Kind функции - PullRequest
0 голосов
/ 30 мая 2018

Как можно использовать встроенное в ISO Fortran Env значение функции KIND, возвращаемое функцией способом, идиоматичным для Fortran 2008?

Обычно в основной программе я могу просто использовать встроенные функции ISO Fortran.следующим образом:

program name here
    use iso_fortran_env
    implicit none
    integer, parameter :: double=REAL64
    real(kind=double) :: some_variable
end program name here

Но, кажется, нет удобного способа использовать эти встроенные функции для внешних функций, поскольку REAL64 и double будут определены только в основной функции, описанной выше.Попытка определить KIND функции в main следующим образом:

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

По крайней мере, в моей системе выдается ошибка несоответствия типов (double определяется как KIND = 8, а значение по умолчанию определяется как KIND =4 в моей системе).Я всегда мог просто использовать real(kind=8) function some_function(), но я бы предпочел не использовать его в интересах переносимости.Кроме того, просто грязно использовать REAL64 из iso_fortran_env в одном месте, только чтобы развернуться и использовать KIND = 8 в другом месте.

Существует ли простой (или, по крайней мере, читабельный) способ сделать это,такие как ниже?

real(kind=REAL64) function some_function()

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Расширение ответа @ chw21:

У вас всегда есть возможность объявить тип результата функции в части спецификации функции и получить доступ к параметрам из модулей с помощью ассоциации хоста внутри нее.

Редактировать : «Как указано @Vladimir F, вы также можете обращаться к переменным по ассоциации хоста из модуля, объявленного внутри тела функции.»

Фактически это единственный способ применить атрибуты к результату функции, такие как указатель, выделение, измерение и т. Д.

Кроме того, вы также можете объявить новое имя для результата функции через суффикс result.

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
0 голосов
/ 30 мая 2018

Вы начинаете свой вопрос и предлагаете решение, и эти решения хорошо работают.Как указывает IanH, в стандартной формулировке есть некоторая неоднозначность, но я прочитал ее как высказывание, что это разрешено, и компиляторы принимают этот синтаксис:

fundef.f90:

real(kind=REAL64) function some_function()
  use iso_fortran_env
  some_function = 1._real64
end

compile:

> gfortran -c funkind.f90 
> 

Вы можете использовать тип, определенный в модуле, используемом внутри функции.Протестировано также с Intel Fortran и Oracle Studio.

В современном Fortran все функции в любом случае должны быть определены в модуле , но если вы хотите, чтобы вы работали с модулем, используемым только внутри функциивозможность здесь.

0 голосов
/ 30 мая 2018

Я обычно пробую это перед публикацией, но я думаю, что это должно работать:

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

Или внутри модуля

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
...