2010-05-21 11 views
28

Gute Praxis Weglassen diktiert, dass Subroutine Argumente in Fortran sollte jedes eine bestimmte Absicht haben (dh intent(in), intent(out) oder intent(inout) wie beschrieben this question):Fortran Intent (INOUT-) gegen die Absicht

subroutine bar (a, b) 
    real, intent(in) :: a 
    real, intent(inout) :: b 
    b = b + a 
    ... 

jedoch keine Absicht, die Angabe gilt Fortran:

subroutine bar (a, b) 
    real, intent(in) :: a 
    real :: b 
    b = b + a 
    ... 

Sind keine wirklichen Unterschiede jenseits der Kompilierung dort für ein Argument angegeben als intent(inout) und ein Argument, ohne einer bestimmten Prüfung Zelt? Gibt es etwas, worüber ich mich Sorgen machen sollte, wenn ich Intents zu älteren, absichtsfreien Code umrüte?

Antwort

20

Nach Das Fortran 2003 Handbuch von Adams, et al., Gibt es einen Unterschied zwischen einem Intent (inout) -Argument und Argument ohne spezifizierte Absicht. Das tatsächliche Argument (d. H. In dem Aufrufer) in dem Intent (Inout) -Fall muss immer definierbar sein. Wenn die Absicht nicht angegeben wird, muss das Argument definierbar sein , wenn die Ausführung des Unterprogramms versucht, das Dummy-Argument zu definieren. definierbar bedeutet Einstellung des Wertes: dummy_arg = 2.0. Natürlich sollte das tatsächliche Argument eine Variable sein, wenn dies getan wird. Für int (inout) muss das eigentliche Argument definierbar sein, ob das Unterprogramm dies tut oder nicht. Wenn keine Absicht angegeben ist, hängt es davon ab, was bei diesem bestimmten Aufruf der Subroutine passiert - wenn die Subroutine die Variable nicht definiert, ist sie in Ordnung; Wenn ja, dann gibt es ein Problem - Fälle wie das Schreiben auf ein tatsächliches Argument, das eine Konstante ist, werden offensichtlich Probleme verursachen.

Dies bedeutet nicht, dass der Compiler alle diese Fälle diagnostizieren wird - was der Standard erfordert einen Compiler zu diagnostizieren ist ein anderes Problem. Es wäre nahezu unmöglich, alle Fehler der Anforderung, die nicht in der Absicht spezifiziert ist, zum Zeitpunkt der Kompilierung zu erkennen, da die Verletzungen vom Laufzeitfluss des Codes abhängen. Es ist viel einfacher für den Compiler, den Intent-Fall zu diagnostizieren und Sie vor Problemen mit dem Code zu warnen.

5

Ihre Frage veranlasst mich zu fragen (viel zu tun, gerade jetzt), ob Sie einen Unterschied im Verhalten finden können, wenn Ihr Code ein PARAMETER als ein tatsächliches Argument übergibt, das Ihr Unterprogramm dann zu schreiben versucht. Ohne eine INTENT-Deklaration könnte der Compiler dies loslassen, was zu merkwürdigem Verhalten führt. Mit der Deklaration würde ich einen Kompilierungsfehler erwarten.

Sie und ich könnten denken, dass es keinen Unterschied zwischen INOUT und keiner INTENT-Deklaration gibt, aber vergessen Sie nicht, dass es viele alte Fortran-Programme gibt und dass Kompatibilität mit älteren Sprachversionen eine wichtige Eigenschaft von new ist Standards. Wenn es richtig (aber zwielichtig) FORTRAN77 war, dann erwarten viele Leute, dass ihr Code mit einem Fortran 90+ Compiler korrekt (immer noch zweifelhaft) bleibt.

Ein kurzer Blick auf den 2003-Standard zeigt an, dass es einen Unterschied zwischen INOUT und keinem INTENT gibt, aber ein genauerer Lesevorgang ist erforderlich. Wenn Sie dies testen, lassen Sie uns Ihre Schlussfolgerungen wissen; wenn ich später Zeit habe, werde ich es selbst testen und Sie wissen lassen.

+3

Ich habe vier Testfälle konstruiert, die versuchen, einen Parameter in einem Unterprogramm zu ändern. Zwei Tests mit externen Subroutinen - d. H. In einer Datei für sich selbst - mit und ohne Absicht (inout). Der Compiler beschwert sich nicht über diese. Dies ist keine Überraschung (keine Schnittstelle) und die resultierenden exe segfaults. Ich habe das Unterprogramm in einem Modul für die letzten beiden Tests stecken und sehe den segfault für den Fall ohne Absicht und einen Compilerfehler ("Tatsächliches Argument bei (1) muss definierbar sein, da das Dummy-Argument 'b' INTENT = OUT/INOUT ") mit der Schnittstelle. Dies ist mit gfortran 4.4.4-2 von einem Debian-System. –

+0

Ausgezeichnet, wir haben beide etwas gelernt. –

+1

Heute werden Parameter in einem schreibgeschützten Speicherbereich abgelegt, was jedoch nicht immer der Fall war. Das berühmte Beispiel in sehr alten Compilern war die Neudefinition von numerischen Konstanten http://coding.derkeiler.com/Archive/Fortran/comp.lang.fortran/2005-01/0485.html –

3

Um die Rolle der Absicht in/out zu verstehen, müssen Sie wissen, dass intern Fortran effektiv Variablen als Referenz übergibt. Dies ist nicht immer das Gleiche, als wenn man tatsächlich durch Referenz geht.

Wenn Sie einen internen Unterabschnitt eines 2-D-Arrays an ein Unterprogramm übergeben, zB: data(i1:i2, j1:j2), kopiert Fortran diese Daten in einen zusammenhängenden Speicherabschnitt und übergibt die neue Adresse an die Routine. Nach der Rückkehr werden die Daten an ihren ursprünglichen Ort zurückkopiert.

Durch Angabe von INTENT kann der Compiler einen der Kopiervorgänge überspringen.

Es fungiert nicht nur als Ausfallsicherheit für das Ändern von Daten, die unverändert bleiben sollen, sondern kann auch Ihren Code beim Umgang mit großen Datensätzen beschleunigen.