> Date: Thu, 15 Oct 1998 12:47:21 -0400
> From: "Peter Shenkin" <[log in to unmask]>
> The only negative you cite is code bulkiness, and indeed this
> is something I put up with. Probably half my lines of code
> SUBROUTINE derivs_alloc( ... )
> ...
> msg = 'derv1'; nword = nderv1
> ALLOCATE( derv1(nderv1), STAT=status )
> IF( status .NE. 0 )THEN
> GOTO 900
> ELSE IF( verbose )THEN
> WRITE( iwrit, '(A,2I8)' ) &
> & 'derivs_alloc: derv1 ALLOCATEd to SHAPE= ', &
> & SHAPE(derv1)
> ENDIF
> ...
> RETURN !!! normal return
> 900 CONTINUE
> error = .TRUE.
> WRITE( 6, '(3A,I20)' ) &
> & 'derivs_alloc: could not ALLOCATE ', &
> & TRIM(msg), '; size= ', nword
> END
> Of course, the calling routine checks "error", sees that it
> is .TRUE., and prints its own name with another message, etc.
I use a similar approach which I think helps with the code bulkiness
problem. I use an internal subprogram (a logical function) to handle
all the error checking. This moves the code away from the primary
thread of execution. It doesn't reduce the code bulkiness (probably
makes it a little worse) but it does reduce the bulkiness visible to
someone trying to read and understand the code.
I would code Peter's example thusly:
SUBROUTINE ...
ALLOCATE( derv1(nderv1) ,STAT=status )
if( ERROR( 'derv1' ) ) goto 900
...
RETURN
900 STOP
contains
logical function ERROR( ConditionString )
character ,intent(IN) :: ConditionString*(*)
ERROR = .FALSE.
SELECT CASE ( ConditionString )
CASE ( 'derv1' )
IF( status .NE. 0 )THEN
ERROR = .TRUE.
WRITE( 6, '(3A,I20)' ) &
& 'derivs_alloc: could not ALLOCATE ', &
& TRIM(msg), '; size= ', nword
ELSE IF( verbose )THEN
WRITE( iwrit, '(A,2I8)' ) &
& 'derivs_alloc: derv1 ALLOCATEd to SHAPE= ', &
& SHAPE(derv1)
ENDIF
CASE DEFAULT
ERROR = .TRUE.
WRITE( 6,* ) 'BugCheck: unimplemented ERROR condition'
END CASE
RETURN
END FUNCTION ERROR
END SUBROUTINE
It's easy to add error conditions and handle recoverable errors to this
framework, since all the variables in the routine are accessable in the ERROR()
function. The code overhead isn't much if there are several places in the
routine where error handling needs to be done. The SELECT may impose a
run-time performance penalty, but I think it's worth it.
-David
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|