Passing parameter as parameter in Fortran-90?

前提是你 提交于 2020-05-29 06:55:06

问题


Suppose I have a subroutine:

subroutine foo(x, Nx)
    implicit none
    integer, intent(IN) :: x
    integer, intent(IN) :: Nx

    select case(x)
        case (1)
            write(*,*) "Minimum value"
        case (Nx)
            write(*,*) "Maximum value"
        case default
            write(*,*) "Somewhere in-between"
    end select
end subroutine foo

Suppose my driver looks like this:

program main
    implicit none

    interface
        subroutine foo(x,Nx)
            integer, intent(IN)  :: x
            integer, intent(IN)  :: Nx
        end subroutine foo
    end interface

    integer, parameter :: Nx = 100
    integer :: x

    call foo(20, Nx)

end program main

The above program will not compile because in the subroutine, case (Nx) is invalid. Specifically, ifort 16 gives the following error:

error #6601: In a CASE statement, the case-value must be a constant expression.

In other words, even though Nx is effectively declared as a subroutine constant via intent(IN), it needs to be either a literal constant or parameter of type integer.

Are there any ways to make the case statement accept Nx as the constant parameter we know it to be? Is there some way to declare Nx to be a passed-in parameter?

I realize that in this simple, short example, an if-then-elseif-else-end block would suffice, but then I wouldn't know the answer to this question. :-)


回答1:


Just use an if statement. A subroutine argument (which you call parameter) is certainly not a parameter (named constant). The intent(in) doesn't make it effectively a parameter, it is just a promise you will not change it, but there are ways to circumvent that. The case statement needs a compile-time constant.




回答2:


You ask whether there is a way to "accept Nx as the constant parameter we know it to be?". We don't know that Nx forms a constant expression, and we indeed know that it doesn't.

The only way for Nx to be a constant expression is for Nx to be a named constant. Being a named constant is incompatible with being a dummy argument, even one which is argument associated, with intent(in) or no intent attribute, with a named constant.

Conceptually, the subroutine foo is an external procedure as far as the main program is concerned (there's an interface block). This means that one would expect it to be compiled as a stand-alone thing, being linked in at that later stage. It should be valid regardless of its ultimate use. [That said, even when it isn't an external procedure the first part still holds as far as the language specification goes.]

Naturally, there are other ways to have Nx a named constant in the subroutine if you don't want to rewrite this using an if construct.



来源:https://stackoverflow.com/questions/32553490/passing-parameter-as-parameter-in-fortran-90

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!