【问题标题】:Assertions in FortranFortran 中的断言
【发布时间】:2017-09-06 23:17:17
【问题描述】:

Fortran 是否有与 C assert 等效的标准函数/关键字?

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

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

【问题讨论】:

    标签: fortran preprocessor assert


    【解决方案1】:

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

    定义一个全局参数如:

    logical, parameter :: debugging = .true.
    

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

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

    if (debugging) call assert(...)
    

    一旦你想发布代码,将debugging 的值设置为.false. 我希望,虽然我没有测试过,所以你可能会关心,任何当前的 Fortran 编译器都可以在遇到死代码时删除它等价于

    的表达式
    if (.false.) call assert(...)
    

    并且您发布的代码不会因为对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
    

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

    use, non_intrinsic :: assertions, assert=>assert_dbg
    

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

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

    【讨论】:

    • 另一种可能性是在两个不同的文件(assert_debug.f90、assert_rel.f90)中有两个断言函数的实现,并根据发布/调试构建在构建系统中选择正确的文件。
    • 对我来说,通过更改断言模块中的一行来在断言函数之间切换似乎更好。为此,请添加 interface assertmodule procedure assert_dbg,您可以将其更改为 module procedure assert_prd
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      对于固定形式的源代码,可以使用-fd-lines-as-comments 进行发布构建,使用-fd-lines-as-code 进行调试构建(Intel Fortran -d-lines) 并使用自定义断言:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-03
        • 2013-01-14
        相关资源
        最近更新 更多