Arguments cause headaches
27 August 2014Having spent some time taking a look at a problem for a researcher where a program would quit with the dreaded:
Segmentation fault (core dumped)
It led to a common problem of argument chasing.
Fortran arguments
Fortran (unlike C) by default passes arguments by memory address (i.e. pointers). This speeds up performance since it does not copy memory which can be very time-consuming. Before the advent of Fortran 90 with features such as modules; interfaces; and intent, arguments were treated as blobs of memory and errors in code were harder to spot. Lets look at an example:
c File: main.f PROGRAM main IMPLICIT NONE INTEGER i CALL sub1(i) WRITE(6,*) "i = ", i END
With the subroutine defined as:
c File: sub1.f SUBROUTINE sub1(i) IMPLICIT NONE INTEGER i i = 0 END
Compiling and running the code produces:
i = 0
Argument chasing
A problem that can occur is changing the call to pass a constant:
CALL sub1(10)
When sub1 sets i
to zero, what should occur? The original error (i.e. segmentation fault) is what can occur – and does with compilers on our systems. The code is trying to write to a block of memory which is not a variable. The original software with this error had passed this argument down a few routines before it tried to write to it.
Advice when using Fortran
Fortran 90 introduced modules and interfaces, when used with intent property of arguments can define how arguments should be treated. For example adding the following interface in main.f:
INTERFACE SUBROUTINE sub1 (i) INTEGER, INTENT(INOUT) :: i END SUBROUTINE sub1 END INTERFACE
Makes it clear that i
is to be read and written to (or in the example above we could use INTENT(OUT)
since we only write to it). Using intent allows the compiler to know how the argument is to be used and therefore check its use, therefore not using intent is not the same as specifying INTENT(INOUT)
. Alternatively wrapping the sub1 routine inside a module would have had a similar effect if the intent was placed in the arguments of the actual routine.
Having fixed the error the researcher could run the code and perform the research they wanted to do – rather than having to debug the problem themselves.