Gibt es in Fortran eine Ausnahmebehandlungsstruktur wie in Python?
try:
print "Hello World"
except:
print "This is an error message!"
Wenn dies nicht der Fall ist, wie können Ausnahmen am einfachsten behandelt werden?
Ausnahmen als solche gibt es in Fortran nicht, daher gibt es keine Ausnahmebehandlung.
Aber Sie können mit Standard Fortran etwas Ähnliches tun wie mit der Ausnahmebehandlung - es gibt sogar eine Abhandlung darüber Arjen Markus, "Ausnahmebehandlung in Fortran" .
Die gebräuchlichste Schreibweise ist die Verwendung einer (ganzzahligen) Rückgabevariable, die den Fehlercode angibt:
subroutine do_something(stat)
integer :: stat
print "Hello World"
stat = 0
end subroutine
und im Hauptprogramm tun
call do_something(stat)
if (stat /= 0) print *,"This is an error message!"
In diesem Artikel werden andere Möglichkeiten beschrieben, beispielsweise das Definieren eines dedizierten abgeleiteten Typs für Ausnahmen, in dem auch eine Fehlermeldung gespeichert werden kann. Das dort genannte Beispiel, das einer Exception am nächsten kommt, verwendet alternative Rückgaben für Unterprogramme (bei Funktionen jedoch nicht möglich):
subroutine do_something(stat, *)
integer :: stat
!...
! Some error occurred
if (error) return 1
end subroutine
und im Hauptprogramm tun
try: block
call do_something(stat, *100)
exit try ! Exit the try block in case of normal execution
100 continue ! Jump here in case of an error
print *,"This is an error message!"
end block try
Bitte beachten Sie, dass für das Blockkonstrukt ein Compiler erforderlich ist, der Fortran 2008 entspricht.
Ich habe so etwas noch nie gesehen :)
Es gibt Vorschläge (siehe Steve Lionels Kommentar unten), um dem nächsten Fortran-Standard eine Ausnahmebehandlung hinzuzufügen. Siehe hier zum Beispiel: Ausnahmebehandlung - BCS Fortran Specialist Group
Dies hat anscheinend eine lange Geschichte in Fortran (siehe noch einmal Steves zweiten Kommentar unten)
Angesichts der Tatsache, dass viele try-except
-Anwendungsfälle für die E/A-Verarbeitung vorgesehen sind, sollten Sie wissen, dass alle FORTRAN-E/A-Funktionen einen ERR
-Spezifizierer haben, der im Fehlerfall auf eine Zeilenbezeichnung verweist. Zum Beispiel:
C2345678
READ( UNIT=5, FMT=10, ERR=30, IOSTAT=N ) X
10 FORMAT(I5)
WRITE( UNIT=6, FMT=20, ERR=30, IOSTAT=N ) X
20 FORMAT(I5)
30 WRITE( *, * ) 'I/O error # ', N, ', on 1'
natürlich könnte man die WRITE
ausführbare Datei durch einen anderen Ausdruck ersetzen, um eine Form von except
Funktionalität zu erreichen.
Obwohl dies keine richtige "Ausnahmebehandlung" ist, fand ich die folgende Unterroutine praktisch nützlich
SUBROUTINE RAISE_EXCEPTION(message)
INTEGER i
CHARACTER(LEN=*) message
PRINT *,message
i=1
i=1/(i-i)
ENDSUBROUTINE
das kann aufgerufen werden, wenn eine Fehlerbedingung auftritt, z.
IF (var<0) CALL RAISE_EXCEPTION('Error: var should be positive!')
Wenn der Code mit den Optionen gfortran -ffpe-trap=zero
Und -fbacktrace
(-fpe0
Mit ifort) kompiliert wird, wird der Code gestoppt (aufgrund der absichtlichen Division durch Null in der Subroutine) und Ein Aufrufstapel wird gedruckt. Wenn Sie den Code debuggen, wird der Prozess nicht abgebrochen (auch wenn die Ausführung angehalten wird), sodass Sie Variablen, Aufrufstapel usw. vom Debugger aus untersuchen können.