2016-08-05 36 views
2

Ich habe Probleme beim Schreiben eines zuweisbaren Array in einem abgeleiteten Typ mit Namelists verschachtelt. Ein minimales Beispiel wird unten gezeigt. Wie kann ich das Programm so ändern, dass das zuweisbare Array innerhalb des abgeleiteten Typs so funktioniert, als wäre es nicht verschachtelt?Wie schreibe ich ein zuweisbares Array in einem abgeleiteten Typ mit Namenslisten?

program test 

    implicit none 

    type struct_foo 
     integer, allocatable :: nested_bar(:) 
    end type struct_foo 

    integer, allocatable :: bar(:) 
    type(struct_foo) :: foo 
    ! namelist/list/foo, bar 
    namelist/list/bar 

    allocate(bar(5)) 
    bar = [1:5] 

    allocate(foo%nested_bar(5)) 
    foo%nested_bar=[1:5] 

    write(*,list) 

end program test 

Mit dem foo kommentiert aus der Namensliste, es funktioniert gut, die Ausgabe produzieren:

>> ifort -traceback test_1.f90 -o test && ./test 
test_1.f90(20): error #5498: Allocatable or pointer derived-type fields require a user-defined I/O procedure. 
    write(*,list) 
--------^ 
compilation aborted for test_1.f90 (code 1) 
+0

Können Sie uns sagen, welchen Compiler Sie verwenden? – chw21

+0

iforort (IFORT) 15.0.3 20150408 – lenzinho

Antwort

3

As:

&LIST 
BAR  =   1,   2,   3,   4,   5 
/

Mit foo enthalten ist, das Programm zu kompilieren, schlägt fehl Die Fehlermeldung besagt, dass Sie eine benutzerdefinierte abgeleitete Typ-E/A-Prozedur (UDDTIO) bereitstellen müssen. Dies ist für die Eingabe/Ausgabe eines Objekts mit einer zuweisbaren oder Zeigerkomponente erforderlich.

Wie das Objekt des abgeleiteten Typs in der Datei formatiert wird, unterliegt vollständig der Kontrolle der UDDTIO-Prozedur.

Ein Beispiel mit einem sehr einfachen Ausgabeformat finden Sie weiter unten. Typischerweise würde eine UDDTIO Verfahren Implementierung Namensliste Ausgabe ein Ausgabeformat verwenden, die mit den anderen Aspekten der Namensliste Ausgabe konsistent war und in der Regel gäbe es auch eine entsprechende UDDTIO Prozedur, die dann in der Lage waren, die formatierten Ergebnisse zurück in lesen.

module foo_mod 
    implicit none 

    type struct_foo 
    integer, allocatable :: nested_bar(:) 
    contains 
    procedure, private :: write_formatted 
    generic :: write(formatted) => write_formatted 
    end type struct_foo 
contains 
    subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg) 
    class(struct_foo), intent(in) :: dtv 
    integer, intent(in) :: unit 
    character(*), intent(in) :: iotype 
    integer, intent(in) :: v_list(:) 
    integer, intent(out) :: iostat 
    character(*), intent(inout) :: iomsg 

    integer :: i 

    if (allocated(dtv%nested_bar)) then 
     write (unit, "(l1,i10,i10)", iostat=iostat, iomsg=iomsg) & 
      .true., & 
      lbound(dtv%nested_bar, 1), & 
      ubound(dtv%nested_bar, 1) 
     if (iostat /= 0) return 
     do i = 1, size(dtv%nested_bar) 
     write (unit, "(i10)", iostat=iostat, iomsg=iomsg) & 
      dtv%nested_bar(i) 
     if (iostat /= 0) return 
     end do 
     write (unit, "(/)", iostat=iostat, iomsg=iomsg) 
    else 
     write (unit, "(l1,/)", iostat=iostat, iomsg=iomsg) .false. 
    end if 
    end subroutine write_formatted 
end module foo_mod 

program test 
    use foo_mod 

    implicit none 

    integer, allocatable :: bar(:) 
    type(struct_foo) :: foo 
    namelist/list/foo, bar 

    allocate(bar(5)) 
    bar = [1:5] 

    allocate(foo%nested_bar(5)) 
    foo%nested_bar=[1:5] 

    write (*,list) 
end program test 

Die Verwendung von UDDTIO erfordert offensichtlich einen Compiler, der diese Fortran 2003-Sprachfunktion implementiert.

+0

Danke, Ian. Gibt es einen besonderen Grund, warum die Sprache es nicht erlaubt, dass Namelist direkt von einem zuweisbaren Typ innerhalb eines abgeleiteten Typs schreibt? – lenzinho

+1

Es gibt keine offensichtliche formatierte Darstellung des Zuweisungsstatus einer zuweisbaren Komponente (oder der Semantik und des Zuordnungsstatus einer Zeigerkomponente). Vielleicht wird die Komponente immer zugewiesen - in diesem Fall ist es nicht notwendig, eine nicht zugewiesene Bedingung darzustellen, vielleicht wird die untere Grenze immer eins sein usw. Es wird noch komplizierter, wenn Sie polymorphe Komponenten und Komponenten mit verzögerten Längenparametern betrachten. – IanH

+0

Danke nochmal, Ian. Eine letzte Frage: Warum schreibt nicht (Einheit, "(i10)", iostat = Iostat, iomsg = iomsg) einen Zeilenumbruch nach dem Schreiben von i10? Wie kann der Zeilenumbruch innerhalb der UDDTIO erreicht werden? – lenzinho