2016-11-14 2 views
1

Ich habe eine Fortran-Subroutine, die so aussieht.Fortran seltsame Zuordnung, ist 4294967295 ==. Wahre.?

subroutine load_ed_ecosystem_params() 

    use pft_coms , only : include_these_pft & ! intent(in) 
          , is_tropical   & ! intent(out) 
          , is_liana    ! intent(out) 
    implicit none 
    !---------------------------------------------------------------------------------------! 
    ! This flag should be used to define whether the plant is tropical/subtropical or ! 
    ! not.                     ! 
    !---------------------------------------------------------------------------------------! 
    is_tropical(1:4) = .true. 
    is_tropical(5:11) = .false. 
    is_tropical(12:13) = .false. 
    is_tropical(14:15) = .true. 
    is_tropical(16) = .true. 
    is_tropical(17) = .true. 
    !---------------------------------------------------------------------------------------! 

    !---------------------------------------------------------------------------------------! 
    ! This flag should be used to define whether the plant is a liana or not    ! 
    !---------------------------------------------------------------------------------------! 
    is_liana(1:16) = .false. 
    is_liana(17) = .true. 
    !---------------------------------------------------------------------------------------! 

Die Arrays is_tropicalis_liana und werden in der pft_coms.f90 Datei definiert. Die Arrays nahmen seltsame Werte, also starte ich die ausführbare Datei in gdb. Ich habe die Akte kurz vor dem Auftrag und direkt danach geklaut. Vor der Zuweisung erhalte ich

Breakpoint 1, load_ed_ecosystem_params() at ed_params.f90:87 
87  is_tropical(1:4) = .true. 

(gdb) print is_tropical 
$2 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE.) 

(gdb) print is_liana 
$3 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE.) 

, wie sie sollten, da sie auf diese Weise initialisiert werden. Nach den wenigen nächsten Zeilen läuft ich

(gdb) n 
88  is_tropical(5:11) = .false. 
(gdb) n 
89  is_tropical(12:13) = .false. 
(gdb) n 
90  is_tropical(14:15) = .true. 
(gdb) n 
91  is_tropical(16) = .true. 
(gdb) n 
96  is_tropical(17) = .true. 
(gdb) n 
102 is_liana(1:16) = .false. 
(gdb) n 
103 is_liana(17) = .true. 
(gdb) print is_tropical 
$4 = (4294967295, 4294967295, 4294967295, 4294967295, .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., 4294967295, 4294967295, 4294967295, 4294967295) 
(gdb) print is_liana 
$6 = (.FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., .FALSE., 4294967295) 

Warum die Vektoren, die die ganze Zahl 2^32 zugeordnet sind - 1 anstelle des logischen .true.?

+0

Das sieht wie ein Problem mit GDB aus, das den Wert interpretiert. Aber ich denke, es ist ein .TRUE. eigentlich. Haben Sie ein Problem in Fortran direkt bemerkt? –

+0

Ja, das führte schließlich zu einem SegFault mit Fehler: _forrtl: schwer (408): fort: (2): Index # 1 des Arrays IS_LIANA hat den Wert 65, der größer ist als die Obergrenze von 17_ – Manfredo

+0

Ich denke, dass die segfault hat mit diesem Problem nichts zu tun. Und BTW ist technisch gesehen kein segfault, aber der Compiler überprüft einen Fehler. Sie sollten diese Nachricht lesen und Ihre Grenzen überprüfen. –

Antwort

1

Einige Fortran-Compiler (insbesondere Intel Fortran) verwenden ein Bitmuster von -1, um .TRUE darzustellen, und einige verwenden +1.

Sieht so aus, als ob GDB +1 als .TRUE erwartet. und weiß nicht, dass 4294967295 auch .TRUE. ist, nur in einem anderen Compiler.

Vorzeichenlose Ganzzahl 4294967295 hat das gleiche Bitmuster wie vorzeichenbehaftete Ganzzahl -1. Alle Bits sind auf 1 gesetzt.

Sie können dieses Verhalten ändern, indem Sie -standard-semantics oder -fpscomp logicals. Intel Fortran wird dann +1 als .TRUE verwenden.

+0

Also ich bin mir nicht sicher über deine antwort, einerseits stimmt es das ich mit intel kompiliere, auf der anderen merke ich genau das gleiche verhalten wenn Ich debugge mit 'idb'. Sollte das auch mit dem Intel Debugger passieren? – Manfredo

+0

Es könnte, wer weiß, Intel hat zwei verschiedene Betriebsmodi und IDB ist nur für eines von ihnen vorbereitet. –

+1

Im Allgemeinen Kompilierung mit -check Grenzen (oder -check alle) wird die üblichen Ursachen von segfaults helfen. Es gibt einen ähnlichen gfortran Schalter. – Holmz

Verwandte Themen