Standardkonstrukor
-
@Columbo sagte in Standardkonstrukor:
@john-0
Tatsaechlich habe ich mich gerade mit einem Arbeitskollegen unterhalten, der mir erklaert hat, dass in Fortran die Etiquette besteht, dass man nie einen Parameter aendern sollte, gerade weil dies zu boesen Fehlern fuehrt, wenn man Konstanten etc. als Argumente hat (und ganz frueher, aber das war in den 90ern schon folklore, konnte man auf bestimmten Maschinen sogar die integer literals aendern, weil sie im Datensegment gespeichert waren).Das stimmt eher nicht. Beispiel finden sich etwa in der offiziellen BLAS Referenzimplementation z.B. DGEMM. Es war usus im Kopf der Routine das zu dokumentieren, so dass man wusste wie ein Parameter genutzt werden darf. Aber da reden wir über Fortran77 und älter, und bei so altem Fortran wurden meistens COMMON Blöcke genutzt, bei denen das Problem ohnehin nicht existiert. Ab Fortran90 gibt es das Intent Statement, mit dem man das auch durch den Compiler prüfen lassen kann.
Das sah dann ungefähr so aus.C OLD FORTRAN STYLE C THIS SHORT PROGRAM DEMONSTRATE PARAMETER HANDLING WITHIN FORTRAN C SUBROUTINES AND FUNCTIONS COMMON/FOOCOM/ MODE,RCUT COMPLEX Z DATA Z /(1.0,3.141592654)/ CALL FOO(Z) WRITE(*,*) MODE,RCUT,Z END PROGRAM SUBROUTINE FOO(Z) C IN OUT: Z, /FOOCOM/ RCUT C IN: /FOOCOM/ MODE COMPLEX Z C Die Definition des COMMON Blocks und der Konstante würde man bei größeren Programmen in eine Include datei auslagern. PARAMETER (PI=3.141592654) COMMON/FOOCOM/ MODE,RCUT IF(MODE.EQ.1)THEN RCUT=RCUT*PI Z=Z**2 ELSE RCUT=RCUT*2*PI Z=Z**0.5 ENDIF END SUBROUTINE BLOCK DATA COMMON/FOOCOM/ MODE,RCUT DATA MODE,RCUT /1,3.0/ END
Im aktuellen Fortran wurde man das Programm eher im folgenden Stil formulieren.
program param_new use iso_fortran_env implicit none real(kind=real64), parameter :: PI = 3.141592654 real(kind=real64) :: rcut = 3.0 integer :: mode = 1 complex(kind=real64) :: z = (1.0,PI) call foo(mode, rcut, z) WRITE(*,*) MODE,RCUT,Z contains subroutine foo(mode,rcut,z) integer, intent(in) :: mode real(kind=real64), intent(in out) :: rcut complex(kind=real64), intent(in out) :: z if (mode == 1) then rcut = rcut * PI z = z ** 2 else rcut = rcut * 2 * PI z = z ** 0.5 end if end subroutine foo end program param_new
Ein Fortran Fanatiker wuerde also das
const
sehenNein, da man das in der Regel so nicht gemacht hat. Es gibt genügend Beispiel im Netz wie man das früher gemacht hat, die Variante, die dein Kollege ansprach, ist eher ungewöhnlich.