2014-02-12 142 views
5

Fortran是否具有与C assert相同的标准函数/关键字?Fortran中的声明

我没有找到我在Fortran2003标准中提到的assert。我发现如何使用预处理器的方法很少,但在这个answer中,建议编写自己的断言。是否可以在不使用预处理器的情况下创建这样的用户函数/子程序?

我期望这些断言在发布版本时被禁用。

回答

2

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

3

有条件的编译在Fortran中从未真正引发过,并且没有标准的预处理器。如果让你的预处理器进出虚拟断言程序切换是不是你想解决你可以什么...

定义一个全局参数,如:

logical, parameter :: debugging = .true. 

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

然后写把守的检查,如

if (debugging) call assert(...) 

一旦你要释放的代码,设置的debugging.false.值我希望,虽然我没有做过测试,所以你可能会关心,任何当它遇到一个表达式相当于

if (.false.) call assert(...) 

和您发布的代码将支付任何罚款伪呼叫到assert常规电流Fortran编译可以去除死代码。

另一种方法可能是创建一个模块,我们称之为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 

然后,您可以重命名的子程序,当你他们,如使用-关联:

use, non_intrinsic :: assertions, assert=>assert_dbg 

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

除此之外,请参阅@AlexanderVogt向您推荐的由Arjen Markus撰写的论文。

+0

另一种可能将是具有断言的两种实现在两个不同的文件(assert_debug.f90,assert_rel.f90)中起作用,并根据Release/Debug构建选择构建系统中的正确文件。 – Peter

+0

通过更改断言模块中的单行来切换断言功能似乎更好。为此,可以添加一个'interface assert'和一个'module procedure assert_dbg',你可以更改为'module procedure assert_prd'。 –

1

对于固定形式来源,可以使用用于调试生成-fd-lines-as-comments用于发布版本和-fd-lines-as-code(英特尔Fortran -d-lines) 和使用定制断言:

D  if (assert_condition) then 
D   write(*,*) 'assert message' 
D   call exit(1) 
D  endif