一种可移动的方式来抑制;“未使用的伪参数”;Fortran语言中的警告

一种可移动的方式来抑制;“未使用的伪参数”;Fortran语言中的警告,fortran,warnings,Fortran,Warnings,是否有任何可移植的方法来抑制Fortran中针对特定变量的“未使用的伪参数”警告,类似于C/C++中的技巧 一个激励性的例子(根据Vladimir F的要求)。策略模式,GoF示例,具有不同的换行策略,省略了不必要的细节 module linebreaking type, abstract :: linebreaking_compositor contains procedure(linebreaking_compositor_compose), deferred, pass

是否有任何可移植的方法来抑制Fortran中针对特定变量的“未使用的伪参数”警告,类似于C/C++中的技巧


一个激励性的例子(根据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

正如您所看到的,传递的对象伪参数
linebreaking\u array\u compositor
compose
方法中是必需的,但不在其他两个合成器的相同方法中使用。GFortran抱怨没有使用
这个
,我不想通过为特定文件设置特定规则(如
-Wno unused dummy argument
)使构建过程复杂化。

要禁用关于某些选定的、未使用的dummy argument的警告,我们可能需要执行一些“无操作”操作(例如,虚拟赋值、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

要禁用有关某些选定的、未使用的伪参数的警告,我们可能需要执行一些“无操作”操作(例如,伪赋值、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

我对这个问题没有完全满意的解决办法

无论使用什么简单的源代码构造,都需要小心,以免无意中将带有未使用的伪参数的一致性代码变成不一致性代码。我的经验是,这很容易出错,小心治疗的成本不会超过疾病的成本。现在,通常情况下,我只是忽略编译器输出中的警告

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

对于我知道将定义的非指针、非可分配、非可选、类似于意图(IN)的数字内在类型的伪参数,我使用了一种模式,例如
如果(arg/=0)继续
。消除逻辑比较,对字符使用
LEN(arg)/=0

对于非指针、非可分配、非可选、意图(in)派生类型的伪参数,条件表达式必须特定于派生类型-可能有一个方便的内部类型的不可分配、非指针组件可以测试。在某些情况下,我已将此类组件显式添加到派生类型,否则该派生类型可能为空

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

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


未能定义类似意图(OUT)的参数似乎表明存在编程错误,如果不是,并且已知实际参数始终是可定义的(!)-只需定义参数,可能使用伪值。类似地,参数的定义状态(或指针参数的指针关联状态)的情况“可能未定义”也表明存在潜在的编码/代码设计问题-在调用之前定义相关的实际参数(可能是伪值)。

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

无论使用什么简单的源代码构造,都需要小心,以免无意中将带有未使用的伪参数的一致性代码变成不一致性代码。我的经验是,这很容易出错,小心治疗的成本不会超过疾病的成本。现在,通常情况下,我只是忽略编译器输出中的警告

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

对于我知道将定义的非指针、非可分配、非可选、类似于意图(IN)的数字内在类型的伪参数,我使用了一种模式,例如
如果(arg/=0)继续
。消除逻辑比较,对字符使用
LEN(arg)/=0

对于非指针、非可分配、非可选、意图(in)派生类型的伪参数,条件表达式必须特定于派生类型-可能有一个方便的内部类型的不可分配、非指针组件可以测试。在某些情况下,我已将此类组件显式添加到派生类型,否则该派生类型可能为空

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

在上述所有情况下,使用CONTINUE作为IF语句的操作语句很容易被读者或其他人在源代码中识别