Fortran中的断言

Fortran中的断言,fortran,preprocessor,assert,Fortran,Preprocessor,Assert,Fortran是否有Cassert的标准函数/关键字等价物 我找不到Fortran2003标准中提到的assert。我发现了一些如何使用预处理器的方法,但在这里建议编写自己的断言。不使用预处理器就可以创建这样的用户函数/子例程吗 我希望在发布版本中禁用这些断言。据我所知,标准Fortran中没有这样的语句或函数/子例程。但是,正如您所说的,您可以使用自己的子例程/函数和/或Fortran中的OOP来实现这一目标。请参阅Arjen Markus关于此主题的精彩文章 条件编译在Fortran中从未真

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

我找不到Fortran2003标准中提到的
assert
。我发现了一些如何使用预处理器的方法,但在这里建议编写自己的断言。不使用预处理器就可以创建这样的用户函数/子例程吗


我希望在发布版本中禁用这些断言。

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

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

定义全局参数,例如:

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

然后编写保护测试,例如

if (debugging) call assert(...)
一旦您想要释放代码,请将
调试
的值设置为
.false。
我希望,尽管我还没有测试过这一点,所以您可能会注意,任何当前Fortran编译器在遇到与

if (.false.) call assert(...)
并且您发布的代码不会因为对
assert
例程的伪调用而受到惩罚

另一种方法可能是创建一个模块,我们称之为断言,大致如下:

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\u prd
。但我怀疑编译器可能不会完全消除对空子例程的调用,并且您的生产代码可能会为遇到的每一个断言付出一点代价


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

对于固定格式源代码,可以使用
-fd行作为发布版本的注释,使用
-fd行作为调试版本的代码(英特尔Fortran
-d行
) 并使用自定义断言:

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

另一种可能性是在两个不同的文件(assert_debug.f90、assert_rel.f90)中有两个assert函数的实现,并根据发布/调试版本在构建系统中选择正确的文件。在我看来,最好通过更改assertions模块中的一行来在assert函数之间切换。为此,添加一个
接口断言
和一个
模块过程断言_dbg
,您可以将其更改为
模块过程断言_prd