8

有人可以向我解释虚拟变量或属性对应于解析器/编译器中的哪种抽象吗?

      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)
4

2 回答 2

10

Fortran 通过引用传递。dummy 属性对应于传递给函数的那些变量(XY您的情况下)。参数语句期待一些静态的东西,但由于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属性意味着你只是得到一个指针 - 你不必分配任何空间,因为函数调用中使用的变量已经已分配空间。

于 2009-06-28T16:46:39.840 回答
4

Tim Whitcomb 很好地解释了通话的实际问题。我将尝试更明确地解释这些术语。

虚拟参数是 Fortran 特定的术语。它是其他语言所称的形式参数或类似参数,即它是被调用的对象,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服务很好。这些是不兼容的,因为第一个意味着一个虚拟参数,另一个指定一个命名常量

于 2015-07-23T15:09:47.977 回答