Variable ou constante de module
- Un module peut contenir non seulement des procédures mais aussi des “ variables ou constantes de module ” (à l'extérieur des procédures).
- Ces variables ou constantes doivent être déclarées au-dessus de la
ligne
contains
.
Exemple de déclaration d’une constante de module
module netcdf
implicit none
integer, parameter:: nf90_nowrite = …
contains
subroutine nf90_open(…)
…
end module netcdf
Accès à une constante ou variable de module
- La constante ou variable est accessible de n'importe quelle
procédure du module où elle est déclarée, sans déclaration
use
. - Selon son attribut d’accessibilité, la constante ou variable peut
être lisible ou non, modifiable ou non de l’extérieur du module, via
la déclaration
use
.
Attribut d’accessibilité
public
(attribut par défaut) →lisible et modifiable (modifiable si c’est une variable)protected
(pour une variable, pas pour une constante) →lisible, non modifiableprivate
→ni lisible, ni modifiable
Exemple d’accès à une constante de module
Depuis l’extérieur du module netcdf :
use netcdf, only : nf90_nowrite
Possible parce que nf90_nowrite
a l’attribut public
dans sa
déclaration dans le module netcdf
.
Exemple de déclaration d’un attribut autre que public
module f_m
implicit none
real, private:: p
contains
real function f(…)
…
f = p + …
…
subroutine config_f
read *, p
Un des intérêts d'une variable de module : contourner une interface imposée
Procédure dont l'interface est imposée, parce qu'elle doit être passée en argument d'une procédure de bibliothèque.
Exemple :
- f(x) dépend d'un paramètre p, on veut chercher le zéro de f pour différentes valeurs de p.
- On utilise
rtsafe
.rtsafe
prend en argument une fonction (la fonction dont on cherche le 0).rtsafe
impose que la fonction prenne un seul argument, x.
Intérêt d'une variable de module : exemple
use f_m, only: f, config_f
…
call config_f
print *, rtsafe(f,x1=0., x2=1., xacc=1e-3)
call config_f
print *, rtsafe(f, x1=0., x2=1., xacc=1e-3)
Autre intérêt d’une variable ou constante de module : masquer une implémentation
worker_1
a besoin de transmettre une variable x àworker_2
, maishigh_level
n’en a que faire.- On ne veut pas alourdir
high_level
en faisant apparaître x dedans. On ne veut donc pas passer x via les arguments deworker_1
etworker_2
. - Possibilité de mettre x en variable de module.
With great power comes great danger
- Il peut être très difficile de suivre le fonctionnement d’un programme avec des variables de module publiques : elles peuvent être modifiées de façon cachée à l’intérieur d’une arborescence d’appels.
- Conseil 1 : utiliser les variables de module avec discernement, il faut avoir de bonnes raisons.
- Conseil 2 : éviter les variables de module publiques, donner
toujours au moins l’attribut
protected
.