2014-02-12 10 views
5

Hat Fortran eine Standardfunktion/Schlüsselwortäquivalent für C assert?Behauptungen in Fortran

Ich konnte nicht finden assert erwähnt in Fortran2003-Standard, den ich habe. Ich habe einige Möglichkeiten gefunden, wie man einen Preprozessor verwendet, aber in diesem answer wird vorgeschlagen, eigene Behauptungen zu schreiben. Ist es möglich, eine solche Benutzerfunktion/Subroutine ohne Vorprozessor zu erstellen?

Ich erwarte, dass diese Zusicherungen für Release-Builds deaktiviert sind.

Antwort

2

In Standard Fortran gibt es meines Wissens keine solche Anweisung oder Funktion/Subroutine. Aber - wie Sie gesagt haben - können Sie Ihre eigenen Subroutinen/Funktionen und/oder OOP in Fortran verwenden, um dieses Ziel zu erreichen. Siehe Arjen Markus 'ausgezeichnet paper zu diesem Thema.

3

Die bedingte Kompilierung hat sich in Fortran nie wirklich durchgesetzt, und es gibt keinen Standard-Vorprozessor. Wenn Ihr Pre-Prozessor in die und aus einem Dummy assert Routine zu wechseln ist nicht etwas, das Sie angehen wollen könnten Sie ...

einen globalen Parameter definieren, wie:

logical, parameter :: debugging = .true. 

Wenn Sie von eine nervöse Disposition könntest du dies in ein Modul einfügen und es in jeden Bereich einfügen, in dem es benötigt wird; In meinen Augen scheint es sinnvoll, einen globalen Parameter zu verwenden.

Dann bewacht Tests schreiben wie

if (debugging) call assert(...) 

Sobald Sie den Code freigeben möchten, setzen Sie den Wert von debugging-.false. erwarte ich, obwohl ich nicht getestet haben, dies so zu Ihnen wichtig kann, dass jeder Strom Fortran Compiler kann totem Code entfernen, wenn sie eine entsprechende Angabe

if (.false.) call assert(...) 

und dass Ihre freigegebenen Code begegnet wird keine Strafe für einen Dummy-Anruf an eine assert Routine zahlen.

könnte Ein weiterer Ansatz sein, ein Modul zu schaffen, die es assertions lassen nennen, in diese Richtung:

module assertions 

contains 

    subroutine assert_prd(args) 
    ! declare args 
    end subroutine 

    subroutine assert_dbg(args) 
    ! declare args 
    ! now do do some assertion checking and exception raising, etc 
    end subroutine 

end module assertions 

Sie dann die Subroutinen benennen können, wenn Sie sie verwenden verknüpfen, wie zB:

use, non_intrinsic :: assertions, assert=>assert_dbg 

und ändern Sie das zu assert=>assert_prd, wenn Sie Assertion-Prüfung deaktivieren möchten. Ich vermute jedoch, dass Compiler den Aufruf der leeren Unterroutine nicht vollständig eliminieren können und dass Ihr Produktionscode für jede getroffene Behauptung eine kleine Strafe zahlen kann.

Darüber hinaus finden Sie in der Arbeit von Arjen Markus, dass @AlexanderVogt Sie bezeichnet hat.

+0

Eine andere Möglichkeit wäre, zwei Implementierungen von assert haben Funktion in zwei verschiedenen Dateien (assert_debug.f90, assert_rel.f90) und wählen Sie die richtige Datei im Build-System abhängig von Release/Debug Build. – Peter

+0

Es scheint mir besser zu sein, zwischen den Assert-Funktionen zu wechseln, indem ich eine einzelne Zeile im Assertions-Modul ändere. Fügen Sie dazu eine 'interface assert' mit einer' modul procedure assert_dbg' hinzu, die Sie in 'module procedure assert_prd' ändern können. –

1

Für feste Form Quellen, kann man -fd-lines-as-comments für die Freigabe verwenden baut und -fd-lines-as-code für Debug-Build (Intel Fortran -d-lines) und verwenden, um benutzerdefinierte behaupten:

D  if (assert_condition) then 
D   write(*,*) 'assert message' 
D   call exit(1) 
D  endif