Терминология компилятора Фортрана: фиктивные переменные и атрибуты - PullRequest
6 голосов
/ 28 июня 2009

Может кто-нибудь объяснить мне, какой абстракции в парсере / компиляторе соответствует фиктивная переменная или атрибут?

      PURE SUBROUTINE F(X, Y)
        IMPLICIT NONE
        REAL, INTENT(INOUT) :: X, Y, C
C        REAL :: A, B
C        REAL, SAVE :: C = 3.14E0
        PARAMETER (C = 3.14E0, X = 32, Y = X)
        X = Y + 2 * SIN(Y)
      END

cetin@unique:~/lab/secret/tapenade$ gfortran -x f77 -c 1.f 
1.f:6.37:

        PARAMETER (C = 3.14E0, X = 32, Y = X)                           
                                    1
Error: PARAMETER attribute conflicts with DUMMY attribute in 'x' at (1)
1.f:3.38:

        REAL, INTENT(INOUT) :: X, Y, C                                  
                                     1
Error: Symbol at (1) is not a DUMMY variable

cetin@unique:~/lab/secret/tapenade$ ifort -c 1.f
1.f(3): error #6451: A dummy argument name is required in this context.   [C]
        REAL, INTENT(INOUT) :: X, Y, C
-------------------------------------^
1.f(6): error #6406: Conflicting attributes or multiple declaration of name.   [X]
        PARAMETER (C = 3.14E0, X = 32, Y = X)
-------------------------------^
1.f(6): error #6406: Conflicting attributes or multiple declaration of name.   [Y]
        PARAMETER (C = 3.14E0, X = 32, Y = X)
---------------------------------------^
1.f(6): error #6592: This symbol must be a defined parameter, an enumerator, or an argument of an inquiry function that evaluates to a compile-time constant.   [X]
        PARAMETER (C = 3.14E0, X = 32, Y = X)
-------------------------------------------^
compilation aborted for 1.f (code 1)

Ответы [ 2 ]

9 голосов
/ 28 июня 2009

Фортран проходит по ссылке. Атрибут dummy соответствует тем переменным, которые передаются в функцию (X и Y в вашем случае). Оператор параметра ожидает чего-то статического, но поскольку X - это то, что передается в функцию, это действительно не имеет никакого смысла. Оператор параметров - это способ установки констант - он не имеет ничего общего с параметрами подпрограммы.

Когда вы получаете сообщение о том, что C не является переменной DUMMY, это означает, что он не находит C в списке переменных, которые будут переданы в / из функции - ваше объявление только F(X, Y): нет C в поле зрения. Хотя вы явно не используете атрибут DUMMY, у вас есть атрибут INTENT(INOUT), что означает, что эти переменные соответствуют подпрограмме ввода / вывода.

Чтобы получить то, что вы хотите, у вас есть подпрограмма, которая выглядит примерно так:

subroutine F(X, Y)
    implicit none

    ! These are the dummy variables
    real, intent(inout) :: X, Y

    ! These are the variables in the scope of this subroutine
    real                  :: a, b
    real, parameter, save :: c = 3.14E0

    X = Y + 2*sin(Y)
end subroutine F

Я не совсем уверен, что вы пытаетесь сделать - вы объявляете подпрограмму pure, что означает подпрограмму без побочных эффектов, но вы используете intent(inout) для своих переменных, что означает, что X и Y могут быть изменены в процессе исполнения.

Я бы добавил также, что внутри подпрограммы инициализация переменной в ее операторе объявления, например REAL :: C = 3.14E0, дает переменную с неявным save атрибутом. Однако, если вы хотите, чтобы он был сохранен от звонка к звонку, вы поступили правильно, явно добавив атрибут save, чтобы было ясно, что вы это делаете.

Я не разбираюсь в парсере / компиляторе, но я думаю, что для ответа на ваш вопрос атрибут dummy означает, что вы просто получаете указатель - вам не нужно выделять пробел, так как переменная в вызове функции уже выделено место.

3 голосов
/ 23 июля 2015

Фактическая проблема с вызовом хорошо объяснена Тимом Уиткомбом. Я постараюсь объяснить более четко термины.

Пустой аргумент - это специфический для Фортрана термин. Это то, что другие языки называют формальными параметрами или подобными, т.е. это объект, который называется X и Y (в вашем случае), и ведьма связывается с фактическим аргументом когда вызывается процедура.

Поэтому в:

subroutine s(i)
  integer :: i
end

call s(1)

i является фиктивным аргументом подпрограммы s, в то время как выражение 1 является фактическим аргументом, который передается подпрограмме фиктивному аргументу i.

Атрибуты - это форма указания дополнительных свойств объектов данных или процедур. Атрибуты могут быть указаны с помощью операторов:

real c
intent(in) c
optional c

или они могут быть указаны в одной декларации:

real, intent(in), optional :: c

Таким образом, фиктивный аргумент c является вещественным значением по умолчанию с атрибутами intent(in) и optional.

Конфликтующие атрибуты - это атрибуты, которые нельзя указывать для одного объекта одновременно. Ваш пример с intent(...) и parameter хорошо работает. Они несовместимы, так как первый подразумевает фиктивный аргумент, а другой указывает именованную константу .

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