Терминология компилятора Fortran:Фиктивные переменные и атрибуты

StackOverflow https://stackoverflow.com/questions/1054352

  •  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 хорошо подается.Они несовместимы, поскольку первый подразумевает фиктивный аргумент, а другой указывает именованная константа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top