【发布时间】:2015-12-09 18:53:27
【问题描述】:
假设我有一个子程序:
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
假设我的驱动程序如下所示:
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
上面的程序将无法编译,因为在子程序中,case (Nx) 无效。具体来说,ifort 16 给出以下错误:
错误 #6601:在 CASE 语句中,case-value 必须是常量表达式。
换句话说,即使 Nx 实际上通过intent(IN) 声明为子例程常量,它也必须是字面常量或integer 类型的parameter。
有没有办法让 case 语句接受 Nx 作为我们知道的常量参数?有没有办法将Nx 声明为传入的parameter?
我意识到在这个简单、简短的示例中,一个 if-then-elseif-else-end 块就足够了,但是我不知道这个问题的答案。 :-)
【问题讨论】:
-
仅供参考,您在
"Maximum value之后缺少结束引号。并且可能是::中的integer, parameter Nx。 -
你能定义一个包含你的参数和子程序的模块吗?如果是这样,会有帮助吗?:)
-
顺便说一句,你说“换句话说,即使 Nx 通过
intent(IN)...有效地声明为子例程常量”。我认为问题在于 fortran 需要知道case值在编译时,因此作为子例程常量是不够的。否则,我不明白为什么在不必指定任何常量属性的情况下即时找出值会伤害编译器。 -
@AndrasDeak:其他语言不要求 switch/select/case 构造具有编译时常量(它们通常不是!)。我承认语言规范,但我认为这更像是一个错误而不是一个功能。 (但我知道什么?!:-))我认为模块的想法可能会奏效(Personal ToDo:test this),尽管它不适合这个目的。
-
重点是 case 结构通常可以实现为跳转表,而不是 if-else 分支。 C 具有相同的属性。
标签: parameters fortran fortran90 intel-fortran select-case