Терминология компилятора Fortran:Фиктивные переменные и атрибуты
-
20-08-2019 - |
Вопрос
Может кто-нибудь объяснить мне, какому типу абстракции в анализаторе / компиляторе соответствует фиктивная переменная или атрибут?
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)
Решение
Fortran передается по ссылке.Фиктивный атрибут соответствует тем переменным , которые передаются в функцию (X
и Y
в вашем случае).Оператор parameter ожидает чего-то статического, но поскольку X
это все, что передается в функцию, на самом деле не имеет никакого смысла.Оператор parameter - это способ настройки констант - он не имеет никакого отношения к параметрам подпрограммы.
Когда вы получаете сообщение об ошибке, в котором говорится, что 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
атрибут означает, что вы просто получаете указатель - вам не нужно выделять какое-либо пространство, поскольку для переменной, используемой в вызове функции, уже выделено пространство.
Другие советы
Реальная проблема со звонком хорошо объяснена Тимом Уиткомбом.Я постараюсь более подробно объяснить эти термины.
Фиктивный аргумент это специфичный для фортрана термин.Это то, что другие языки называют формальные параметры или аналогичный, т.е.это объект, который вызывается X
и Y
(в вашем случае) и witch ассоциируется с фактический аргумент когда вызывается процедура.
Поэтому в:
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
хорошо подается.Они несовместимы, поскольку первый подразумевает фиктивный аргумент, а другой указывает именованная константа.