*
@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 sehen
Nein, 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.