Нет предупреждения, но неправильно, если глобальная переменная такая же, как переменная INOUT в подпрограмме - PullRequest
0 голосов
/ 08 марта 2020

У меня вопрос о глобальных и локальных переменных.

Я знаю, что если переменная var является глобальной переменной, у меня не должно быть REAL*8, INTENT(INOUT) :: var в подпрограмме одновременно.

Но я просто сделал это случайно, и никаких предупреждений нет. Иногда код работает хорошо, но иногда бывают большие ошибки. Насколько я понимаю, в некоторых случаях значение var назначается случайным образом, когда подпрограмма заканчивается, как правило, очень большие цифры в моих результатах. Поэтому, даже если нет предупреждений, я определенно должен избегать этого снова.

Я не уверен, правильно ли мое понимание или нет. С нетерпением жду любого комментария! Благодаря.

1 Ответ

2 голосов
/ 08 марта 2020

Боюсь, ваше понимание неверно, и в вашей программе почти наверняка есть ошибки - возможно. Я говорю, вероятно, потому что вы не включили код, показывающий вашу проблему. Без этого кода мне придется догадываться о том, что вы говорите, в будущем всегда включайте полный код, который показывает вашу проблему, облегчает ответ и дает более точные ответы.

Во всяком случае, во-первых, пожалуйста, не используйте реальный * 8. Это не часть Фортрана. Он никогда не был частью Фортрана. Вы не можете полагаться на то, что он делает то, что вы ожидаете.

Во-вторых, в стандартном Фортране нет причины, по которой вы не можете иметь локальную переменную с тем же именем, что и у ассоциации хоста (я полагаю, это это то, что вы подразумеваете под глобальной переменной, но стандарт не использует этот термин, насколько мне известно). Рассмотрим следующую программу. Вы можете видеть, что в панели подпрограмм осуществляется доступ к локальному foo, а в основной программе это переменная модуля foo. Все работает, как и ожидалось:

ian@eris:~/work/stack$ gfortran-8 --version
GNU Fortran (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ian@eris:~/work/stack$ cat scope.f90 
Module module_scope

  Use, Intrinsic :: iso_fortran_env, Only :  wp => real64

  Implicit None

  Real( wp ) :: foo

Contains

  Subroutine bar( foo )

    Real( wp ), Intent( In ) :: foo

    Write( *, * ) foo

  End Subroutine bar

End Module module_scope

Program testit

  Use module_scope, Only : wp, foo, bar

  Implicit None

  foo = 6.0_wp
  Write( *, * ) 'foo = ', foo

  Call bar( 5.0_wp )
  Call bar( 3.0_wp )
  Call bar( 2.0_wp )

End Program testit
ian@eris:~/work/stack$ gfortran-8 -Wall -Wextra -pedantic -std=f2008 -fcheck=all scope.f90 
ian@eris:~/work/stack$ ./a.out
 foo =    6.0000000000000000     
   5.0000000000000000     
   3.0000000000000000     
   2.0000000000000000  

Примечание. Я не говорю, что это хорошая практика - на самом деле я думаю, что это ужасно. Но это не так.

Таким образом, если ваша программа работает не так, как вы ожидаете, и я правильно угадал, что вы описываете, то вам придется искать ошибку в другом месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...