Print

Print


The following message is a courtesy copy of an article
that has been posted as well.


In case anyone else is interested in doing rudimentary "design by
contract" in Fortran, here is a simple subroutine that works for me
using Solaris Fortran 2.0 using the fortran preprocessor fpp.  I'd be
interested in hearing about improvements and portability.

For those who aren't familiar with C-style assertions, they are
enormously useful macro statements that test the truth of a logical
condition.  If the condition isn't met, then the program halts and
prints the line number.  If the program is compiled with -DNDEBUG,
then the assertions are no-ops that are optimized away.

Here's an example of a precondtion test:

--------testit.F90

#include "assert.h"

program test_assert
  implicit none
  real a,b,c
  b=4.
  a=5.
  c=8.
  REQUIRE(a .lt. b)
end program test_assert

when compiled (without -DNDEBUG) and run, the resulting output is:

<peacock /nfs/peacock/local1/datatmp/phil/testf90.dir> testit
Precondition (a .lt. b) failed in file testit.F90 line 0009

Two files are needed to get this to work on Solaris:

----------assert.h

#ifdef	NDEBUG
#define	assert(EX)
#define REQUIRE(EX)
#define ENSURE(EX)
#else
#define   assert(EX) if(.not. ( EX )) call FortranAssert('Assertion',#EX, __FILE__, __LINE__)
#define   REQUIRE(EX) if(.not. ( EX )) call FortranAssert('Precondition',#EX, __FILE__, __LINE__)
#define   ENSURE(EX) if(.not. ( EX )) call FortranAssert('Postcondition',#EX, __FILE__, __LINE__)
#endif	

and:

_________ FortranAssert.f90

subroutine FortranAssert(prepost,expression,filename,linenum)
  character(*), intent(in) :: prepost,expression, filename
  integer,      intent(in) :: linenum
  write(6,'(a,a,a,a,a,a,i4.4)') prepost," (", expression, ") failed in file ", filename," line ",linenum
  stop
end subroutine FortranAssert


-- 
------------------------------------------------------------
Phil Austin  ([log in to unmask])
Department of Geography,                 Tel: (604) 822-2663
University of British Columbia, B.C.     Fax: (604) 822-6150


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%