kdb*_*kdb 9 fortran optional-parameters optional-arguments default-parameters default-arguments
在fortran中,我们可以定义默认参数.但是,如果不存在可选参数,则也不能设置它.当使用参数作为具有默认值的关键字参数时,这会导致类似的笨拙结构
PROGRAM PDEFAULT
CALL SUB
CALL SUB(3)
CONTAINS
SUBROUTINE SUB(VAL)
INTEGER, OPTIONAL :: VAL
INTEGER :: AVAL ! short for "actual val"
IF(PRESENT(VAL)) THEN
AVAL = VAL
ELSE
AVAL = -1 ! default value
END IF
WRITE(*,'("AVAL is ", I0)') AVAL
END SUBROUTINE SUB
END PROGRAM PDEFAULT
Run Code Online (Sandbox Code Playgroud)
就个人而言,我经常遇到意外打字的问题VAL而不是AVAL,即接口中的变量名之间的断开,以及代码中使用的初始化值可能引入运行时错误 - 更不用说这种初始化方式相当冗长.
是否有一些更优雅的方式使用具有默认值的可选参数?
示例写一些类似的东西会更自然
IF(NOT(PRESENT(VAL))) VAL = -1
Run Code Online (Sandbox Code Playgroud)
因为它避免了VALvs AVAL混乱.但它无效,大概是因为Fortran通过引用传递参数,因此如果语句中VAL不存在,则CALL不会与内存关联VAL并VAL = -1导致段错误.
你很好地描述了这种情况.没有别的方法我知道了,这是标准的符合.具有类似命名的局部变量的模式是人们经常使用的模式.另一种选择是放在if (present()) else任何地方,但这很尴尬.
关键是它们是可选参数,而不是默认参数.Fortran没有默认参数.可能会更好,但这不是委员会成员在准备Fortran 90时在80年代所选择的.
在研究这个问题时,我发现你实际上可以使用OPTIONAL和VALUE属性做一些像提议的例子(至少使用gfortran,不知道不同的编译器可能会如何处理它).例如:
PROGRAM PDEFAULT
CALL SUB
CALL SUB(3)
CONTAINS
SUBROUTINE SUB(VAL)
INTEGER, OPTIONAL,VALUE :: VAL
IF(.NOT. PRESENT(VAL)) VAL = -1 ! default value
WRITE(*,'("VAL is ", I0)') VAL
END SUBROUTINE SUB
END PROGRAM PDEFAULT
Run Code Online (Sandbox Code Playgroud)
这是在gfortran的4.9版本中实现的.这里是参数传递约定的文档中的相关解释:
对于可选的伪参数,缺少的参数由NULL指针表示,除了具有VALUE属性的INTEGER,LOGICAL,REAL和COMPLEX类型的标量伪参数.对于那些,隐藏的布尔参数(logical(kind = C_bool),value)用于指示参数是否存在.
我还发现这个讨论很有趣,作为历史背景.
也许有更多知识渊博的人可能会评论这是否是一个坏主意(除了依赖于编译器),但至少从表面看它似乎是一个很好的解决方法.
请注意,此行为不是Fortran标准的一部分,并且取决于给定编译器的实现.例如,使用ifort时的示例代码段错误(版本16.0.2).
| 归档时间: |
|
| 查看次数: |
2702 次 |
| 最近记录: |