Fortran Abfrage- und Ausdruckfunktion oder Unterprogrammname

8

Ist es in Fortran möglich, den Namen der Funktion oder Unterroutine abzufragen, in der ich mich befinde? Das heißt, was stelle ich an Stelle von '???' um es 'my_subroutine' auf dem Bildschirm zu drucken?

%Vor%

Ich versuche einen Weg zu finden, einen benutzerdefinierten Debugger / Profiler zu implementieren, indem ich nur den Such- und Ersetzungsmechanismus eines Texteditors verwende. Eine programmatische Abfrage meiner Position im Code wäre hilfreich.

    
drlemon 11.08.2011, 21:56
quelle

5 Antworten

8

Nein, das kannst du nicht. Was Sie erreichen wollen, heißt Reflexion und ist nicht in Fortran (und nicht in C oder C ++) verfügbar was zählt).

    
Stefano Borini 11.08.2011, 22:12
quelle
6

Sie können den Präprozessor verwenden, um den Dateinamen und die Zeilennummer auszudrucken. Möglicherweise möchten Sie die vordefinierten Präprozessorsymbole __LINE__ und __FILE__ nutzen. Hier ist ein Beispiel:

Ein Präprozessor-Makro ist in der Header-Datei definiert (so dass es an mehreren Stellen verwendet werden kann), rufen Sie es errormsg.h :

auf %Vor%

Dann können Sie diese Header-Datei in Ihre Programm-, Bibliotheks- oder Moduldateien einfügen, zum Beispiel:

%Vor%

Das ERRORMSG("not really an error...") scheint eine seltsame Syntax für Fortran-Code zu sein, wird aber durch den c-Präprozessor ersetzt, der die Makrodefinition verwendet. Wenn das kompiliert wird, sieht es so aus:

%Vor%

Für mein Makro ERRORMSG habe ich gewählt, die Datei 0 zu verwenden, um nach stderr zu drucken. Sie haben natürlich die Freiheit, die Nachricht so zu schreiben, wie Sie wollen, solange dies zu syntaktisch korrektem FORTRAN-Code führt.

Um dies zu kompilieren, müssen Sie Flags an den Compiler übergeben, und sie unterscheiden sich leicht von Compiler zu Compiler. Dies funktionierte für mich zum Beispiel:

%Vor%

Das heißt, für gfortran ruft -cpp den c-Präprozessor vor dem Kompilieren auf. Die Ausgabe aus dem obigen Programm sieht folgendermaßen aus:

%Vor%

Dies kann den gewünschten Effekt haben, besonders wenn Sie nur eine Unterroutine pro Datei schreiben.

    
Yann 12.08.2011 15:13
quelle
3

Ich habe einen einfachen halbautomatischen Ausweg aus dieser Situation gefunden: Verwenden Sie regex, um direkt nach der SUBROUTINE-Deklaration eine fest definierte Definition von __FUNCTION__ hinzuzufügen. Aus dem Makefile wird sichergestellt, dass bei jeder Kompilierung das Makro __FUNCTION__ aktualisiert wird.

Angenommen, wir haben eine F77-Liste, die so aussieht

Datei 'meine-Datei.F'

%Vor%

Ich möchte es in

konvertieren

Datei 'my_file.F.F'

%Vor%

Beachten Sie, dass sich der geänderte Code jetzt in einer anderen Quelldatei befindet: my-file.F.F

Dazu habe ich die folgenden Zeilen zu 'Makefile' hinzugefügt

%Vor%

Unter der Annahme, dass FC als ausführbare Fortran-Compiler definiert ist, sollte dies die folgende Prozedur für alle Unterprogramme in der Datei ausführen:

  • undefiniert ein Makro __FUNCTION__, das möglicherweise früher definiert wurde.
  • Fügen Sie eine __FUNCTION__-Direktive zwei Zeilen unterhalb der SUBROUTINE-Definition hinzu, die den Namen der Subroutine enthält.
  • speichern Sie die Datei unter einem anderen Namen.
  • Kompilieren Sie die neue Quelle in die erforderliche Objektdatei.

Das Ergebnis sollte in diesem Fall my-file.o sein.

Sie haben vielleicht bemerkt, dass ich auch das Makro _S () verwende. Dies ist ein 'stringify'-Makro. Sie müssen es nur zum Anfang Ihrer Fortran-Datei hinzufügen (ich lege es in eine config.h, die ich überall mit einschließe)

Es gibt eine andere Implementierung für GNU und Intel:

%Vor%     
superk 27.09.2013 04:06
quelle
2

Warum schreibst du nicht einfach den Namen der Subroutine in der WRITE-Anweisung?

Sie können den Namen der Subroutine nicht programmatisch (dynamisch) angeben oder ändern, daher sehe ich keinen Grund, auf diese Weise auf sie zuzugreifen ( dazu ): obwohl ich mir nicht sicher bin Es ist unmöglich, irgendwie darauf zuzugreifen, ich bin mir ziemlich sicher, dass es der falsche Weg ist ... du wirst dir mehr Schwierigkeiten machen, als das zu tun, als nur hart zu programmieren.

Übrigens, warum versuchen Sie es trotzdem auszudrucken? Wäre eine gut formulierte Diagnosemeldung nicht aussagekräftiger?

    
Rook 11.08.2011 22:09
quelle
1

In Compilern gibt es manchmal nicht standardmäßige Funktionen, mit denen Sie drucken können, wo Sie gerade sind. Diese sind sehr compilerspezifisch und sollten nur zum Debuggen verwendet werden.

In gfortran können Sie die Unterroutine BACKTRACE verwenden. Aus dem Handbuch:

  

BACKTRACE zeigt eine Backtrace an einer beliebigen Stelle im Benutzercode.   Die Programmausführung wird danach normal fortgesetzt.

Die Ausgabe wird wie eine Fehlermeldung aussehen, aber es kann hilfreich sein.

    
Vladimir F 17.07.2017 08:56
quelle

Tags und Links