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 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.


Anmelden zum Antworten