Fortran中的断言

Pet*_*ter 5 preprocessor fortran assert

Fortran是否具有C的标准函数/关键字等价物assert

assert在Fortran2003标准中找不到提到的.我发现如何使用预处理器的方法很少,但在这个答案中建议编写自己的断言.是否可以在不使用预处理器的情况下创建此类用户功能/子程序?

我希望这些断言对于发布版本是禁用的.

Hig*_*ark 8

条件编译在 Fortran 中从未真正流行过,也没有标准的预处理器。如果让您的预处理器切换进出一个虚拟断言例程不是您想要解决的问题,您可以......

定义一个全局参数,例如:

logical, parameter :: debugging = .true.
Run Code Online (Sandbox Code Playgroud)

如果你是一个神经质的人,你可以把它放到一个模块中,并将它使用-关联到每个需要它的范围;在我看来,使用全局参数在这里似乎是一种合理的方法。

然后编写受保护的测试,例如

if (debugging) call assert(...)
Run Code Online (Sandbox Code Playgroud)

一旦您想发布代码,请将 的值设置debugging.false. 我期望的值,尽管我尚未对此进行测试,因此您可能会关心,任何当前的 Fortran 编译器在遇到等效于的表达式时都可以删除死代码

if (.false.) call assert(...)
Run Code Online (Sandbox Code Playgroud)

并且您发布的代码不会因为对assert例程的虚拟调用而受到惩罚。

另一种方法可能是创建一个模块,让我们称之为assertions,沿着这些路线:

module assertions

contains

  subroutine assert_prd(args)
    ! declare args
  end subroutine

  subroutine assert_dbg(args)
    ! declare args
    ! now do do some assertion checking and exception raising, etc
  end subroutine

end module assertions
Run Code Online (Sandbox Code Playgroud)

然后,您可以在使用关联它们时重命名子例程,例如:

use, non_intrinsic :: assertions, assert=>assert_dbg
Run Code Online (Sandbox Code Playgroud)

并将其更改为assert=>assert_prd要关闭断言检查时。我怀疑编译器可能不会完全消除对空子例程的调用,并且您的生产代码可能会为遇到的每个断言付出一点代价。

除此之外,请参阅 @AlexanderVogt 推荐给您的 Arjen Markus 的论文。


Ale*_*ogt 3

据我所知,标准 Fortran 中没有这样的语句或函数/子例程。但是 - 正如您所说 - 您可以在 Fortran 中使用自己的子例程/函数和/或 OOP 来实现此目标。请参阅 Arjen Markus关于此主题的优秀论文。