1

在处理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保证某些行为?

4

3 回答 3

3

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

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

除了编译器优化的技巧之外,如果您想对类似于 C++ 的默认参数或函数重载的事物进行编译时解析,那么请考虑在泛型名称后面使用多个特定过程,一个带有“可选”参数的特定变体,另一个没有。

于 2015-02-22T19:44:36.510 回答
1

这取决于(您还期望什么?:-)

如果您使用最新版本的 gfortran,并且在至少一个分支中做了大量工作,并使用 LTO 或将所有内容放入一个文件中,编译器将为您克隆该函数(通过不断传播)。否则,可能不会。如果您想知道该过程foo是否已被克隆,请foo.*constprop在程序集文件中使用 grep for。

于 2015-02-22T14:56:21.837 回答
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
于 2015-02-23T15:15:38.290 回答