一种可移植的方法来抑制"未使用的伪参数"在Fortran警告

时间:2016-05-28 14:13:04

标签: fortran warnings

是否有任何可移植的方法来抑制"未使用的伪参数"在Fortran中警告一个类似于C / C ++中(void)var;技巧的特定变量?

一个动机的例子(根据Vladimir F的要求)。策略模式,具有不同换行策略的GoF示例,省略了不必要的细节。

module linebreaking

  type, abstract :: linebreaking_compositor
  contains
    procedure(linebreaking_compositor_compose), deferred, pass(this) :: compose
  end type

  abstract interface
    subroutine linebreaking_compositor_compose(this)
      import linebreaking_compositor
      class(linebreaking_compositor), intent(in) :: this       
    end subroutine linebreaking_compositor_compose
  end interface

  type, extends(linebreaking_compositor) :: linebreaking_simple_compositor
  contains
    procedure, pass(this) :: compose => linebreaking_simple_compositor_compose
  end type linebreaking_simple_compositor

  type, extends(linebreaking_compositor) :: linebreaking_tex_compositor
  contains
    procedure, pass(this) :: compose => linebreaking_tex_compositor_compose
  end type linebreaking_tex_compositor

  type, extends(linebreaking_compositor) :: linebreaking_array_compositor
  private
    integer :: interval
  contains
    procedure, pass(this) :: compose => linebreaking_array_compositor_compose
  end type linebreaking_array_compositor

contains

  subroutine linebreaking_simple_compositor_compose(this)
    class(linebreaking_simple_compositor), intent(in) :: this
    print *, "Composing using a simple compositor."
  end subroutine linebreaking_simple_compositor_compose

  subroutine linebreaking_tex_compositor_compose(this)
    class(linebreaking_tex_compositor), intent(in) :: this
    print *, "Composing using a TeX compositor."
  end subroutine linebreaking_tex_compositor_compose

  subroutine linebreaking_array_compositor_compose(this)
    class(linebreaking_array_compositor), intent(in) :: this
    print *, "Composing using an array compositor with interval", this%interval, "."
  end subroutine linebreaking_array_compositor_compose

end module linebreaking

正如您所看到的,this的{​​{1}}方法中需要传递对象伪参数compose,但未在其他两个合成器的同一方法中使用。 GFortran抱怨linebreaking_array_compositor没有被使用,我不想通过为特定文件设置特定规则(如this)来使构建过程复杂化。

2 个答案:

答案 0 :(得分:3)

我没有完全满意的解决方案。

需要谨慎使用任何简单的源构造,它不会无意中将符合代码的未使用的伪参数转换为不符合代码。我的经验是很容易弄错,要小心治愈费用不超过疾病的费用。这些天我经常忽略编译器输出中的警告。

(从我的角度来看,使用预处理器的成本远远高于实际警告的成本 - 因为代码不再符合标准。)

对于我所知道的非指针,非可分配,非可选,类似INTENT(IN)的数字内部类型的伪参数,我使用了IF (arg /= 0) CONTINUE这样的模式。消除LOGICAL的比较,使用LEN(arg) /= 0作为CHARACTER。

对于派生类型的非指针,不可分配,非可选,intent(in)伪参数,条件表达式必须特定于派生类型 - 也许有一个方便的不可分配的非指针可以测试的内在类型的组件。在某些情况下,我已经明确地将这样的组件添加到派生类型,否则可能是空的。

对于可选的伪参数,请测试参数的存在。对于已知已定义关联状态的指针伪参数,请测试关联状态。对于可分配的参数,请测试分配状态。

在上述所有情况下,使用CONTINUE作为IF语句的操作语句很容易通过读者或某种文本搜索模式在源代码中识别。在启用优化的情况下进行编译时,合理的优化编译器可能会完全消除这种无意义的测试。

如果没有定义类似INTENT(OUT)的参数,则可能会出现编程错误,如果没有,并且已知实际参数总是可定义的(!) - 只需定义参数,可能使用虚拟值。类似地,参数的定义状态(或指针参数的指针关联状态)可能未定义的情况也表明潜在的编码/代码设计问题 - 在此之前定义相关的实际参数(可能是虚拟值)调用

答案 1 :(得分:2)

要禁用某些选定的,未使用的伪参数的警告,我们可能需要做一些"无操作"事情(例如虚拟任务,IF测试,获取地址等)。作为一种这样的方法,如何定义像

这样的宏
#define nop(x) associate( x => x ); end associate

并将其用作

  subroutine linebreaking_simple_compositor_compose(this)
    class(linebreaking_simple_compositor), intent(in) :: this
    nop( this )
    print *, "Composing using a simple compositor."
  end subroutine linebreaking_simple_compositor_compose

在我的计算机上,ifort-14和gfortran> = 4.8接受了这种用法,并没有使用-warn或-Wall发出警告。另一方面,Sun fortran 8.7不接受这个,因为还没有关联支持...(我真的希望它会支持后者!)

下面附有一个小测试代码:

module mymod
    implicit none
    type T
        integer :: n
    endtype
contains
    subroutine mysub( this )
        class(T) :: this
        nop( this )
    endsubroutine

    subroutine mysub2( ptr )
        type(T), pointer :: ptr
        nop( ptr )
    endsubroutine
end

program main
    use mymod
    type(T) :: a
    type(T), pointer :: p
    call mysub( a )
    call mysub2( p )
endprogram