是否有任何可移植的方法来抑制"未使用的伪参数"在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
)来使构建过程复杂化。
答案 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