Fortran - перекомпилировать программу с 32-битной на 64-битную машину

У меня есть очень старая программа, которую я хочу запустить на своем 64-битном компьютере. Есть много обесцененных заявлений. Во время отладки я обнаружил, что многие переменные становятся NaN или Infinity... Следовательно, я изменил переменные с 4 байтов на 8 байтов (т.е. REAL на REAL*8), но теперь расчеты и результаты значительно отличаются на обоих компьютерах. Может ли кто-нибудь объяснить мне, действительно ли это имеет значение, если я использую более длинные типы и почему на 32-битном компьютере все было в порядке, а на 64-битном я получаю значения Infinity и NaN?

P.S. Я использую компилятор gfortran с -fbackslash -ffixed-line-length-0 -std=legacy -g -O0 -fno-inline параметрами

С уважением, kozooh


person kozooh    schedule 26.07.2013    source источник
comment
Вы используете gfortran на обоих компьютерах?   -  person M. S. B.    schedule 26.07.2013
comment
Нет, на 32-битной я использую компилятор g77.   -  person kozooh    schedule 26.07.2013


Ответы (1)


Ваша проблема, вероятно, связана с различиями между компиляторами, а не между битовыми уровнями машин. Например, некоторые компиляторы FORTRAN 77 неявно применяют save ко всем локальным переменным процедуры (подпрограммы и функции). Этого не требует стандарт, и на такое поведение нельзя полагаться. Это часто вызывает проблемы, когда устаревшая программа компилируется современным компилятором, который требует использования save, если локальные переменные должны сохранять свои значения при вызовах процедуры. Я не знаю, есть ли у g77 такая "фича". Вы можете включить это поведение в gfortran с помощью параметра компилятора -fno-automatic.

РЕДАКТИРОВАТЬ: рассмотрите:

  subroutine MySub
  logical FirstCall
  save FirstCall
  data FirstCall / .TRUE. /
  integer I

  if ( FirstCall ) then
     I = 0
     FirstCall = .FALSE.
  end if

  I = I + 1

  write (6, *) "Call", I

  end

  program main

  integer j

  do j=1, 4
     call MySub ()
  end do

  end program main

Скомпилировано с помощью g77 (без опций компилятора), вывод:

 Call 1
 Call 2
 Call 3
 Call 4

Локальная переменная I сохраняет свое значение при вызовах MySub. Итак, похоже, что g77 сохраняет локальные переменные, даже если они не запрашиваются с помощью save. По крайней мере, на уровне оптимизации по умолчанию.

Скомпилированный с помощью gfortran с параметрами fbackslash -ffixed-line-length-0 -std=legacy -g -O0 -fno-inline результат будет таким же. Теперь измените на -O3, и результат будет таким:

 Call           1
 Call           2
 Call           3
 Call         129

Иногда I сохраняет свое значение, иногда нет.

Измените одну строку программы на: save FirstCall, I, и значение всегда сохраняется:

 Call 1
 Call 2
 Call 3
 Call 4

Попробуйте -fno-automatic ...

person M. S. B.    schedule 26.07.2013