Terminologie du compilateur Fortran: Variables factices et attributs
-
20-08-2019 - |
Question
Quelqu'un peut-il m'expliquer à quelle sorte d'abstraction dans l'analyseur / compilateur une variable ou un attribut factice correspond?
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)
La solution
Fortran passe par référence. L'attribut factice correspond aux variables transmises à la fonction (X
et Y
dans votre cas). L'instruction de paramètre attend quelque chose de statique, mais comme C
correspond à tout ce qui est passé dans la fonction, cela n'a aucun sens. L’instruction de paramètre est un moyen de configurer des constantes - elle n’a rien à voir avec les paramètres d’un sous-programme.
Lorsque vous obtenez le message d'erreur indiquant que DUMMY
n'est pas une variable F(X, Y)
, cela signifie que la recherche INTENT(INOUT)
ne figure pas dans la liste des variables qui seront transmises à la fonction - votre déclaration est seulement pure
: aucun intent(inout)
en vue. Bien que vous n'utilisiez pas explicitement l'attribut REAL :: C = 3.14E0
, vous disposez de l'attribut save
, ce qui signifie que ces variables correspondent à l'entrée / la sortie du sous-programme.
Pour obtenir ce que vous voulez, vous auriez un sous-programme qui ressemblerait à quelque chose comme:
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
Je ne suis pas tout à fait sûr de ce que vous essayez de faire: vous déclarez un sous-programme dummy
, ce qui signifie un sous-programme sans effets secondaires, mais vous utilisez <=> pour vos variables, ce qui signifie que <= > et <=> peuvent être modifiés en cours d'exécution.
J'ajouterais également qu'à l'intérieur d'un sous-programme, l'initialisation d'une variable dans son instruction de déclaration telle que <=> génère une variable avec un attribut implicite <=>. Toutefois, si vous souhaitez que cette opération soit sauvegardée, vous avez pris les mesures qui s'imposaient en ajoutant explicitement l'attribut <=> pour indiquer clairement que c'est ce que vous faites.
Je ne suis pas un parseur / compilateur, mais je pense que pour répondre à votre question, l'attribut <=> signifie que vous obtenez juste un pointeur - vous n'avez pas besoin d'allouer d'espace, car la variable l’espace est déjà utilisé dans l’appel de la fonction.
Autres conseils
Tim Whitcomb a bien expliqué le problème actuel de l'appel. Je vais essayer d'expliquer plus explicitement les termes.
L'argument factice est un terme spécifique à Fortran. C’est ce que d’autres langages appellent paramètres formels ou similaires, c’est-à-dire que l’objet est appelé X
et Y
(dans votre cas) et qui est associé à un argument réel à l'appel de la procédure.
Donc dans:
subroutine s(i)
integer :: i
end
call s(1)
le i
est un argument fictif du sous-programme s
tandis que l'expression 1
est l'argument réel transmis au sous-programme à l'argument factice c
.
Les attributs sont une forme de spécification de propriétés supplémentaires d'objets de données ou de procédures. Les attributs peuvent être spécifiés à l’aide des instructions suivantes:
real c
intent(in) c
optional c
ou ils peuvent être spécifiés dans une seule déclaration:
real, intent(in), optional :: c
Ainsi, l'argument factice intent(in)
est un réel par défaut avec les attributs optional
et intent(...)
.
Les attributs en conflit sont des attributs qui ne peuvent pas être spécifiés pour un objet à la fois. Votre exemple avec parameter
et <=> sert bien. Celles-ci sont incompatibles car le premier implique un argument factice et le second spécifie une constante appelée .