Terminologia del compilatore Fortran: variabili e attributi fittizi
-
20-08-2019 - |
Domanda
Qualcuno può spiegarmi a quale tipo di astrazione nel parser / compilatore corrisponde una variabile o un attributo fittizio?
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)
Soluzione
Fortran passa per riferimento. L'attributo fittizio corrisponde a quelle variabili che vengono passate alla funzione (X
e Y
nel tuo caso). L'istruzione di parametro prevede qualcosa di statico, ma poiché C
è tutto ciò che viene passato nella funzione, non ha alcun senso. L'istruzione parametro è un modo per impostare le costanti: non ha nulla a che fare con i parametri di una subroutine.
Quando viene visualizzato l'errore che indica che DUMMY
non è una F(X, Y)
variabile, significa che non sta trovando INTENT(INOUT)
nell'elenco di variabili che verranno passate dentro / fuori dalla funzione: la dichiarazione è solo pure
: nessun intent(inout)
in vista. Anche se non stai usando l'attributo REAL :: C = 3.14E0
esplicitamente, hai l'attributo save
, il che significa che queste variabili corrispondono all'input / output della subroutine.
Per ottenere ciò che desideri, avresti una subroutine simile a:
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
Non sono del tutto sicuro di cosa stai cercando di fare: stai dichiarando una dummy
per le tue variabili, il che significa che <= > e <=> possono essere modificati nel corso dell'esecuzione.
Aggiungo anche quello all'interno di una subroutine, inizializzando una variabile nella sua dichiarazione di dichiarazione come <=> restituisce una variabile con un attributo implicito <=>. Se vuoi che venga salvato da una chiamata all'altra, hai fatto la cosa giusta aggiungendo esplicitamente l'attributo <=> per chiarire che è quello che stai facendo.
Non sono un tipo parser / compilatore, ma penso che per rispondere alla tua domanda, l'attributo <=> significhi che stai solo ottenendo un puntatore: non devi allocare spazio, poiché la variabile utilizzato nella chiamata di funzione ha già allocato spazio.
Altri suggerimenti
Il vero problema con la chiamata è ben spiegato da Tim Whitcomb. Proverò a spiegare più esplicitamente i termini.
Argomento fittizio è un termine specifico di Fortran. È ciò che altre lingue chiamano parametri formali o simili, ovvero è l'oggetto che si chiama X
e Y
(nel tuo caso) e la strega viene associata a un argomento reale quando viene chiamata la procedura.
Pertanto in:
subroutine s(i)
integer :: i
end
call s(1)
i
è un argomento fittizio della subroutine s
mentre l'espressione 1
è l'argomento effettivo che viene passato alla subroutine all'argomento fittizio c
.
Attributi sono una forma di specifica di proprietà aggiuntive di oggetti dati o procedure. Gli attributi possono essere specificati usando le istruzioni:
real c
intent(in) c
optional c
oppure possono essere specificati in un'unica dichiarazione:
real, intent(in), optional :: c
In questo modo l'argomento fittizio intent(in)
è un valore predefinito reale con gli attributi optional
e intent(...)
.
Attributi in conflitto sono attributi che non possono essere specificati per un oggetto contemporaneamente. Il tuo esempio con parameter
e <=> funziona bene. Questi sono incompatibili poiché il primo implica un argomento fittizio e l'altro specifica una costante denominata .