2016-04-08 9 views
1

Ich habe ein Programm in FORTRAN geschrieben, es ist ein einfaches Multiplikationsprogramm. Es scheint auf einem Computer gut zu funktionieren (kompiliert ohne Warnungen und Ausgabe ist korrekt), aber wenn ich den Ordner auf einen anderen Computer scacke, kompiliert es gut ohne Warnungen aber die Ausgabe ändert sich in eine Zufallszahl, nicht sicher, warum das ist? Es gibt zwei Ausgaben, einer ist der Algorithmus in Rekursion und der andere ist iterativ. Rekursion funktioniert gut, aber iterativ gibt den Fehler an. Ich habe make sauber gemacht, und ich habe auch versucht, den Ordner in einen neuen sauberen Ordner zu ändern, immer noch das gleiche Problem.Code funktioniert auf einem Computer und kompiliert (ohne Warnung und Compilerfehler) auf einem anderen Computer, hat aber Laufzeitfehler

Version des einen auf es funktioniert: GNU Fortran (Debian 4.9.2-10) 4.9.2

Version des einen mit falschen Ausgang: GNU Fortran (Debian 4.4.5-8) 4.4. 5

program multiplication 

    integer(kind = 8) :: multiplier, multiplicand, rcursvmultply, itratvmultply 

    write(*,*) "multiplier?" 
    read(*,*) multiplier 

    write(*,*) "multiplicand?" 
    read(*,*) multiplicand 

    write(*,*) rcursvmultply(multiplier, multiplicand) 

    write(*,*) itratvmultply(multiplier, multiplicand) 
end program 

recursive function rcursvmultply(multiplier, multiplicand) result(answer) 

    integer(kind = 8), intent(in) :: multiplier, multiplicand 
    integer(kind = 8) :: answer 

    if (multiplier == 0) then 
     answer = 0 
    else if (multiplier == 1) then 
     answer = multiplicand 
    else if ((multiplier > 1) .and. (mod(multiplier, 2) == 0)) then 
     answer = rcursvmultply((multiplier/2), (multiplicand*2)) 
    else if ((multiplier > 1) .and. (mod(multiplier, 2) == 1)) then 
     answer = (multiplicand + (rcursvmultply((multiplier/2), (multiplicand*2)))) 
    end if 
end function rcursvmultply 

integer(kind = 8) function itratvmultply(multiplier, multiplicand) 

    integer(kind = 8) :: multiplier, multiplicand 

    do while (multiplier > 0) 
     if ((mod(multiplier, 2)) == 1) then 
      itratvmultply = (multiplicand + itratvmultply) 
     end if 
     multiplier = multiplier/2 
     multiplicand = multiplicand*2 
    end do 
end function itratvmultply 

ich habe auch die folgende Warnung auf dem Computer, es funktioniert nicht vor sich:

make: Warning: File `Makefile' has modification time 4.6 s in the future 
make: warning: Clock skew detected. Your build may be incomplete. 

Für die oben Warnung, die ich danach auf dem ursprünglichen Computer und scp sauber haben, es doesn Scheint nicht werde es los. Wenn ich jedoch clean mache, wird die Warnung auf diesem Computer nicht erneut angezeigt. Ich bin mir nicht sicher, warum das so ist.

+0

Warum die so lange und hässlich 'integer (Art = 8)' ', wenn integer (li)' 'mit li' irgendwo so definiert ist viel besser (und kürzere)? (benenne 'li' in das um, was du willst ...) –

+0

Auf gfortran 4.9 benutze' -fsanitize = Adresse, undefiniert' und der Compiler sollte sich beschweren. Valgrind sollte sich auch beschweren. –

+1

Sie erhalten eine Warnung, da die Systemuhr auf der Originalmaschine der der zweiten Maschine voraus ist.Da Marken im Cache gespeichert werden, müssen Sie eine "make clean" auf der zweiten Maschine machen, so dass die Dateien, die 'make' generiert, mit der Uhr der zweiten Maschine mit Zeitmarken versehen sind. Nachdem ich all das gesagt habe, denke ich nicht, dass das das Problem ist, das Sie haben. – TriskalJM

Antwort

2

Wenn diese Linie in itratvmultply

itratvmultply = (multiplicand + itratvmultply) 

wird zuerst die Ergebnisvariable (dh itratvmultply) ausgeführt ist garantiert keinen besonderen Wert haben; Es wurde nicht explizit zugewiesen. Dies bedeutet, dass die rhs der Aufgabe, effektiv, Junk ist. wenn auf einem Computer

Die Symptome, die Sie ganz erklärlich berichten sind (unter Verwendung einer Version eines Compilers und einem unbekannten (für uns) Satz von Kompilierungsoptionen) der Compiler den Wert 0 während auf einem anderen Computer (verschiedene Compiler-Version setzt, möglicherweise verschiedene Optionen) kein solcher Wert wird zur Verfügung gestellt und die Variable bekommt, was auch immer die Bits und Bytes gerade sind.

Sie denken vielleicht, dass die Compiler Variablen 0 setzt, wenn das Programm startet. Das ist nicht durch den Fortran-Sprachstandard garantiert. Und es ist üblich, dass Compiler bei niedrigen Optimierungsebenen beim Programmstart Variablen auf 0 setzen, aber auf höheren Ebenen nicht.

Um dies zu beheben, die Linie

itratvmultply = 0 

in Ihrem Code vor das erste Mal ist die Variablen auf dem rhs eine Zuweisung erscheinen. Überprüfen Sie die Dokumentation Ihres Compilers, um herauszufinden, wie Sie gewarnt werden können, wenn Sie nicht initialisierte Variablen verwenden.

Und @ TriskalJM Kommentar beantwortet Ihre Frage über den lustigen Futurismus im Make-Prozess.