是"现在()"在编译时进行内在评估

时间:2015-02-22 14:41:22

标签: fortran fortran90 optional-arguments

optional中处理fortran个参数时,我认为使用present()内在分支是典型的,即:

subroutine foo(ii,jj)
    implicit none
    integer, intent(in) :: ii
    integer, optional   :: jj

    if (present(jj)) then
! do something
    else
! do something else
    end if

end subroutine foo

我的假设(来自C++世界)是present()希望是编译时构造,并且不存在任何关联的运行时性能损失。我希望编译器能够(应该要求?)优化上面显示的if语句,具体取决于是否调用foo(ii)foo(ii,jj)

编译器在实践中如何处理present()内在函数? fortran规范是否保证某些行为?

3 个答案:

答案 0 :(得分:3)

PRESENT是一个运行时概念 - 在某种程度上,参数的存在可能取决于程序的各个方面,这些方面直到运行时才能确定(基于从文件或类似文件中读取的输入)。

在C ++程序中实现等效的PRESENT同样也是一个运行时概念。请注意,C ++的默认参数功能与Fortran的可选参数功能并不完全相同(尽管它可能是等效实现的一部分)。

除了编译器优化聪明之外,如果你想要编译类似于C ++的默认参数或函数重载的时间解析,那么考虑使用通用名称后面的多个特定过程,一个具有“可选”参数的特定变体,另一个不

答案 1 :(得分:1)

这取决于(你还期待什么?: - )

如果你使用gfortran的最新版本,并在至少一个分支中做了很多工作,并使用LTO或将所有内容放在一个文件中,编译器将为你克隆该函数(通过常量传播)。否则,可能不是。如果要查看是否已克隆过程foo,请在汇编文件中找到foo.*constprop的grep。

答案 2 :(得分:1)

具有可选参数的一个子例程的替代方案是两个子例程,一个带有参数,另一个没有,共享相同的接口。我不认为这样做会产生运行时间成本,而不是给子程序的两个版本赋予不同的名称。原理上,它看起来像这样:

interface foo
   module procedure foo_1,foo_2
end interface foo

contains

subroutine foo_1(ii)
! some code

subroutine foo_2(ii,jj)
! some code