Fortran: Fortran 95: Fortran 95-Erweiterungen

Aus Wikibooks
<<< zur Fortran-Startseite
<< Fortran 95 Fortran 2003 >>
< Von der modularen zur objektorientierten Programmierung Offizielle Fortran 95-Erweiterungen >


Hier sind jene ISO/IEC-Standards angeführt, die nicht Teil des Original-Fortran 95-Standards sind, sondern erst später als offizielle Fortran 95-Erweiterungen formuliert wurden. Etliche Fortran 95-Compiler bieten diese Features derzeit noch nicht oder nur teilweise.

Zeichenketten variabler Länge[Bearbeiten]


Diese Fortran 95-Erweiterung ermöglicht in einfacher Weise das Arbeiten mit Zeichenketten variabler Länge. Die notwendigen Datenelemente und Funktionen sind im Modul iso_varying_string hinterlegt. Die nötigen Programmabläufe zur dynamische Anpassung des jeweils erforderlichen Speicherplatzes übernehmen somit die Unterprogramme dieses Moduls. Eine explizite Begrenzung der maximalen Zeichenkettenlänge ist nicht vorgesehen. Einschränkungen ergeben sich nur durch Hardwarerestriktionen bzw. die Programmkomplexität.

In den getesteten aktuellen Fortran 95-Compilern (gfortran, g95 und ifort) ist mit Stand 01.01.2007 diese Funktionalität noch nicht inkludiert. Zur Nutzung dieses Features mit diesen Compilern ist deshalb der Download und die Einbindung einer der o.a. Moduldateien erforderlich (oder man schreibt selbst ein entsprechendes standardkonformes Modul).


Beispiel:

Fortran 90/95-Code (free source form)
program bsp
  use iso_varying_string
  implicit none
  
  type( varying_string ) :: str

  str = "Wiki"
  write (*,*) len(str)
  write (*,*) char(str)

  str = str // "books"
  write (*,*) len(str)
  write (*,*) char(str) 

! Ausgabe 
!   4
!   Wiki
!   9
!   Wikibooks
end program bsp

Compilieren, Linken:

gfortran -o bsp iso_vsta.f95 bsp.f90


Prinzipiell gelten für Zeichenketten mit variabler Länge die gleichen generisch-intrinsischen Funktionsbezeichner wie für normale Zeichenketten. Auch Stringkonkatenation, Zuweisung und Vergleichsoperationen sind wie gewohnt erlaubt. Zuätzlich kommen noch einige neue Funktionen hinzu:

Funktionsbezeichner Kommentar
var_str Datentypkonvertierung. charactervarying_string
get, put, put_line I/O
insert Einfügen eines Teilstrings
replace Ersetzen eines Teilstrings
remove Entfernen eines Teilstrings
extract Extrahierung eines Teilstrings
split Einen String in zwei Strings splitten.

Bedingte Compilierung[Bearbeiten]

Mannigfaltig sind die Gründe, welche den Einsatz bedingter Compilierung (conditional compilation, Kurzform: coco) erstrebenswert erscheinen lassen. Seien es die unterschiedlichen Betriebssystemkonventionen zur Vergabe von Pfad- und Dateinamen, unterschiedliche Anforderungen an Entwickler- und Releaseversionen eines Programmes oder auch spezielle internationale Marktbedürfnisse, die Programmvarianten erfordern. All diese Bedürfnisse und noch viel mehr kann coco befriedigen.

Weder g95, noch gfortran oder ifort bieten bisher von Haus aus die Möglichkeit zur "conditional compilation". Es gibt aber externe Tools zur ISO/IEC 1539-3, die als Präprozessor fungieren können und somit das gewünschte Verhalten erzeugen, z.B. das Programm coco.


Beispiel:

Die Datei bsp.fpp:

?? integer, parameter :: varianteA = 1, varianteB = 2
?? integer :: flag = 1
program bsp
?? if ( flag == varianteA ) then
   write (*,*) "Variante A"
?? else if (flag == varianteB) then
   write (*,*) "Variante B"
?? endif  
end program bsp

mit der Set-Datei bsp.set:

?? integer :: flag = 2
?? alter: delete

ergibt nach einem Präprozessorlauf coco bsp folgendes Fortran-Programm bsp.f90

program bsp
   write (*,*) "Variante B"
end program bsp


Beispiel:

Wird die coco-Anweisung alter: delete in der Set-Datei weggelassen, so werden die überflüssigen Zeilen nicht gelöscht, sondern nur auskommentiert (shift). Standardmäßig entspricht dies beim coco-Präprozessor einer alter: shift3-Set-Anweisung (!?>). Die Set-Datei bsp.set

?? integer :: flag = 2

würde mit der obigen bsp.fpp-Datei nach einem coco bsp also diesen Fortran-Code liefern

!?>?? integer, parameter :: varianteA = 1, varianteB = 2
!?>?? integer :: flag = 1
program bsp
!?>?? if ( flag == varianteA ) then
!?>   write (*,*) "Variante A"
!?>?? else if (flag == varianteB) then
   write (*,*) "Variante B"
!?>?? endif
end program bsp
!?>?? This was produced using the following SET file
!?>?? integer :: flag = 2

Floating-point Exceptions[Bearbeiten]

Im Fortran 2003-Standard sind Module betreffend IEEE 754-Standard (IEEE Standard for Binary Floating-Point Arithmetic) enthalten. Näheres dazu wird im Fortran 2003-Kapitelabschnitt Die intrinsischen IEEE-Module beschrieben.

Allocatable Components[Bearbeiten]

Diese Erweiterung bezieht sich auf das Schlüsselwort allocatable. In Standard-Fortran 90/95 ist die dynamische Allokation von Speicherplatz für Felder mit dem Attribut allocatable eigentlich nur in einem lokalen Kontext möglich. Der Technical Report 15581 fordert, dass solche Felder darüber hinaus auch in den Anwendungsbereichen

  • Rückgabewert von Funktionen
  • Unterprogrammparameter
  • Feldelemente in Datenverbunden

uneingeschränkt verwendbar sein sollen.

Die Enhanced Data Type Facilities werden bereits standardmäßig vom aktuellen g95-, gfortran-, ifort- und Sun-Fortran-Compiler unterstützt.


Beispiel: Rückgabewert

Fortran 90/95-Code (free source form)
program bsp
  implicit none
    
  write ( *, * ) fun_all( 5 )
  write ( *, * ) fun_all( 7 )

! Ausgabe:
!   1 2 3 4 5
!   1 2 3 4 5 6 7

  contains
    function fun_all( n )
      implicit none
  
      integer, dimension( : ), allocatable :: fun_all
      integer, intent( in )                :: n
      integer                              :: j, st
  
      allocate( fun_all( n ), stat = st )

      if( st == 0 ) then  
        forall( j = 1 : n )
          fun_all(j) = j
        end forall	
      else	
        write( *, * ) "Allocate-Fehler"
      end if
  end function fun_all
end program bsp


Beispiel: Unterprogrammparameter

Fortran 90/95-Code (free source form)
program bsp
  implicit none
  
  integer, dimension( : ), allocatable :: dynarr
  integer                              :: j
  	  

  allocate( dynarr( 3 ) )

  forall( j = 1 : 3 )
    dynarr( j ) = j * 2
  end forall

  call fun_all( dynarr ) 
  
  write( *, * ) "Out: ", dynarr   

  deallocate( dynarr )
  allocate( dynarr( 5 ) )
  
  forall( j = 1 : 5 )
    dynarr( j ) = j * 3
  end forall
  
  call fun_all( dynarr )    

  deallocate( dynarr )


! Ausgabe:
!   Argument: 2 4 6
!   (De)Allocate im UP: 88 99
!   Out:  88 99
!   Argument: 3 6 9 12 15
!   (De)Allocate im UP: 88 99


  contains
    subroutine fun_all( a )
      implicit none
      
      integer, dimension( : ), allocatable, intent( inout ) :: a

      write( *, * ) "Argument:", a 
      
      deallocate( a )
      allocate( a (2) )
      a(1) = 88
      a(2) = 99

      write( *, * ) "(De)Allocate im UP:",  a       
   end subroutine fun_all
end program bsp

Mit Standard-Fortran 90/95 könnten sie zwar das allozierte Feld als Parameter aus dem Hauptprogramm an das Unterprogramm übergeben, dort wäre es aber nicht als allocatable kennzeichenbar und somit im Unterprogramm nicht in der gezeigten Art und Weise (de)allozierbar. Mittels Standardkonformitäts-Compileroptionen, z.B.

  • Intel Fortran Compiler: -stand
  • g95, gfortran: -std=f95

ist überprüfbar, welche Möglichkeiten Standard-Fortran 95 bietet und welche Eigenschaften den Erweiterungen zuschreibbar sind.


Beispiel: allocatable array im Datenverbund

Fortran 90/95-Code (free source form)
program bsp
  implicit none
  

  type struktur
    integer                              :: nr
    integer, dimension( : ), allocatable :: arr      
  end type struktur


  type( struktur ) :: a1, a2
  
  allocate( a1%arr( 5 ) )
  allocate( a2%arr( 2 ) )
  
  a1%nr     = 9453
  a1%arr(1) = 1
  a1%arr(5) = 5

  a2%nr     = 9454
  a2%arr(1) = 11
  a2%arr(2) = 22
  
  write ( *, * ) "a1 =" , a1%nr, a1%arr
  write ( *, * ) "a2 =",  a2%nr, a2%arr

! Ausgabe:
!   a1 = 9453 1 0 0 0 5
!   a2 = 9454 11 22
end program bsp



<<< zur Fortran-Startseite
<< Fortran 95 Fortran 2003 >>
< Von der modularen zur objektorientierten Programmierung Offizielle Fortran 95-Erweiterungen >