首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Fortran中将运行时if替换为编译时if

在Fortran中将运行时if替换为编译时if
EN

Stack Overflow用户
提问于 2018-05-30 07:04:57
回答 1查看 259关注 0票数 2

我有一个子例程,它在中间包含一个简单的if语句,我想去掉它。原因是,我预先知道该语句是真是假,这是基于调用发生的位置,而不是基于输入数据。这甚至更有吸引力,因为它是1行代码,如果它真的不做太多事情的话。

现在有一个额外的逻辑输入,它只用于if语句,它被调用了两次-一次使用"false“,一次使用"true”。

本质上,我想让if语句在编译期间工作,但#ifdef不允许同一个子例程有两种不同的用法/配置。

愚蠢的解决方案是完全复制子例程,并使一个实例具有"true“段,而另一个实例仅具有"false”段。

然而,除此之外,这远远不是优雅的(并且有99.9%的相似性),这是一个打开的麻烦,一旦子例程在未来被改变。

我要指出的是,我的意思不是重载子例程(至少不是在“传统”意义上),尽管这是一种相同的一般概念。

所以我的问题是-有没有解决这种情况的方案,或者我将不得不把它作为一个运行时的if语句,并有一个额外的逻辑true/false输入?

我用的是Fortran 90/95。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-30 07:52:31

所以我的理解是代码应该是这样的:

代码语言:javascript
复制
module mymod
    implicit none
contains
    subroutine mysub(a, l)
        integer, intent(inout) :: a
        logical, intent(in) :: l
        a = mod(a**3, 53)
        if (l) then
            a = a + 1
        else
            a = a - 1
        end if
    end subroutine mysub
end module mymod


program myprog
    use mymod
    implicit none
    integer :: b
    b = 10
    call mysub(b, .TRUE.)
    print *, b
    call mysub(b, .FALSE.)
    print *, b
end program myprog

您还会担心mysub子例程的效率并不高,因为它有一条if语句,即使编译器在编译时知道它每次都会采用哪条路径。

在进一步研究这一点之前,我强烈建议您评估一下是否有必要这样做。您所能做的一切都会降低代码的可读性和可维护性,并且可能最多只能带来轻微的性能提升。

您可以编写两个不同的子例程,并在单独的文件中包含相同的部分,然后将其INCLUDE到两个子例程中,如下所示:

same.inc:

代码语言:javascript
复制
        integer, intent(inout) :: n
        n = mod(n**3, 53)

sub.f90:

代码语言:javascript
复制
module mymod
    implicit none
contains
    subroutine mysub_true(n)
        include 'same.inc'
        n = n + 1
    end subroutine mysub_true
    subroutine mysub_false(n)
        include 'same.inc'
        n = n - 1
    end subroutine mysub_false
end module mymod

与预处理器一起,您甚至可以全力以赴:

mysub.inc:

代码语言:javascript
复制
#if PATH == 1
#define SUB_NAME mysub_true
#else
#define SUB_NAME mysub_false
#endif

    subroutine SUB_NAME(n)
        integer, intent(inout) :: n
        n = mod(n**3, 53)
#if PATH == 1
        n = n + 1
#else
        n = n - 1
#endif
    end subroutine SUB_NAME

#undef SUB_NAME
#undef PATH

mymod.F90:

代码语言:javascript
复制
module mymod
    implicit none
contains

#define PATH 1
#include mysub.inc

#define PATH 0
#include mysub.inc

end module mymod

myprog.F90:

代码语言:javascript
复制
program myprog
    use mymod
    implicit none
    integer :: b
    b = 10
    call mysub_true(b)
    print *, b
    call mysub_false(b)
    print *, b
end program myprog

并使用

代码语言:javascript
复制
gfortran -c -o mymod.o -cpp mymod.F90
gfortran -o myprog myprog.F90 mymod.o

这是否使其更容易阅读或更难阅读取决于相同部分的复杂程度。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50594188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档