Я пишу программу в Fortran 95 (для компиляции с помощью gfortran), содержащую подпрограмму, выполняющую определенное вычисление. Как было предложено в «Fortran 95/2003 для ученых &« Инженеры »от SJ Chapman, я пытаюсь остановить подпрограмму при возникновении ошибки и« бросить »[1] флаг ошибки, который является« catch »ed [1 ] вызывающей программой, которая предпримет все необходимые действия. В идеале, я собираюсь что-то вроде:Как остановить подпрограмму и поднять флаг?
! Pseudo-code
PROGRAM my_prog
integer :: error_flag
CALL my_subr (<input_args>, <output_args>, error_flag)
! Also error_flag is an output: 0 -> everything OK, 1 -> error
IF (error_flag /= 0) THEN
WRITE (*,*) 'Error during execution of "my_subr"'
ELSE
... do something ...
END IF
END PROGRAM my_prog
Как я могу остановить подпрограмму и корректно обрабатывать ошибки?
Ниже приведен пример: «деление» subroutine
принимает целочисленное входное значение и итеративно делит его на значение, которое является входным значением, уменьшенным на количество шагов-1. Когда такое значение достигает нуля, флаг должен быть поднят, и подпрограмма должна выйти без выполнения деления на ноль.
SUBROUTINE division (inval, outval, error_flag)
IMPLICIT NONE
INTEGER, INTENT(IN) :: inval
REAL, INTENT(OUT) :: outval
INTEGER, INTENT(OUT) :: error_flag ! 0 -> OK, 1 -> error
INTEGER :: i
REAL :: x
error_flag = 0
x = REAL(inval)
DO i = 0, 10
IF (inval-i == 0) error_flag = 1
! How can I gracefully exit now?
x = x/REAL(inval-i)
END DO
END SUBROUTINE division
PROGRAM my_prog
IMPLICIT NONE
REAL :: outval
INTEGER :: error_flag
CALL division (8, outval, error_flag)
IF (error_flag == 1) THEN
WRITE (*,*) 'Division by zero'
ELSE
WRITE (*,*) 'Output value:', outval
END IF
END PROGRAM my_prog
Примечания:
[1] Я заимствование (в, вероятно, несоответствующим образом) жаргон C++ 's.
В вашем примере используется флаг ошибки. Чем больше вы этого не сделаете? У вас была проблема с этим? Fortran ближе к C в этом отношении (C использует возвращаемые значения очень похожим образом). –
Внутри подпрограммы вы должны использовать ту же логику, что и ваша вызывающая программа, - оберните потенциально неприятный код внутри какой-либо логики, чтобы перейти к концу процедуры без дополнительной суматохи при возникновении ошибки. –
@VladimirF: Проблема не в вышеупомянутом псевдокоде, а в 'подпрограмме': допустим, у меня есть цикл, и я сталкиваюсь с делением на ноль. Я хотел бы поднять флаг _ before_ деление выполняется, _not_ выполнить деление и сразу же «выйти» подпрограмму. Как я могу это сделать? –