Reputation: 8870
Is there any portable way to suppress an "unused dummy argument" warning in Fortran for a specific variable similar to the (void)var;
trick in C/C++?
A motivational example (by a request from Vladimir F). The strategy pattern, GoF example with different line-breaking strategies, unnecessary details omitted.
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
As you can see the passed-object dummy argument this
is required in compose
method of linebreaking_array_compositor
, but is not used in the same method of two other compositors. GFortran complains about this
not being used, and I don't want to complicate the build process by having specific rules (like -Wno-unused-dummy-argument
) for specific files.
Upvotes: 3
Views: 2776
Reputation: 19
What I have been using without issue for some time is a macro:
#define _UNUSED_DUMMY(x) if (.false.) print*,shape(x)
Upvotes: 1
Reputation: 21431
I have no entirely satisfactory solution to the problem.
Care needs to be take with whatever simple source construct gets used that it doesn't inadvertently turn conforming code with an unused dummy argument into non-conforming code. My experience has been that it is easy to get this wrong, be careful that the cost of the cure does not exceed the cost of the disease. More often than not these days, I just ignore the warning in the compiler's output.
(From my perspective, use of the preprocessor comes with a cost far greater than that of the actual warning - in that the code is no longer standard conforming.)
For non-pointer, non-allocatable, non-optional, INTENT(IN)-like dummy arguments of numeric intrinsic type that I know will be defined I use a pattern such as IF (arg /= 0) CONTINUE
. Eliminate the comparison for LOGICAL, use LEN(arg) /= 0
for CHARACTER.
For non-pointer, non-allocatable, non-optional, intent(in) dummy arguments of derived type, the conditional expression has to be specific to the derived type - perhaps there is a convenient non-allocatable, non-pointer component of intrinsic type that can be tested. In some cases I have explicitly added such a component to a derived type that might otherwise be empty.
For optional dummy arguments, test the presence of the argument. For pointer dummy arguments that are known to have defined association status, test the association status. For allocatable arguments, test the allocation status.
In all the cases above the use of CONTINUE as the action statement for an IF statement is easy enough to identify in source by a reader or some sort of text search pattern. When compiling with optimisation enabled, a reasonable optimising compiler is likely to completely eliminate this otherwise pointless test.
Failure to define an INTENT(OUT)-like argument plausibly suggests a programming error, if not, and the actual argument is known to always be definable (!) - just define the argument, perhaps with a dummy value. Similarly, the situation where the definition status of an argument (or the pointer association status of a pointer argument) may be undefined also suggests a latent coding/code design issue - define the relevant actual argument (perhaps will a dummy value) prior to the call.
Upvotes: 4
Reputation: 7395
To disable the warning about some selected, unused dummy argument, we probably need to do some "no operation" thing (e.g. dummy assignment, IF tests, getting the address, etc). As one such approach, how about defining a macro like
#define nop(x) associate( x => x ); end associate
and using this as
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
On my computer, ifort-14 and gfortran >=4.8 accepted this usage, giving no warning with -warn or -Wall. On the other hand, Sun fortran 8.7 did not accept this because there is no ASSOCIATE support yet... (I really hope it will support the latter!)
A small test code is attached below:
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
Upvotes: 5