Cet article concerne la déclaration des arguments muets tableaux avec profil transmis
Voici un exemple tiré de LMDZ. Nous montrons un appel et l'interface de la procédure appelée.
Version actuelle | En déclarant les arguments tableaux avec profil transmis | |
---|---|---|
Appelant |
REAL masque(iip1,jjp1) REAL mask(iim,jjp1) … DO j = 1, jjp1 mask(i,j) = masque(i,j) ENDDO … CALL rugosite(imdep, jmdep, dlon, dlat, champ, . iim, jjp1, rlonv, rlatu, champint, mask) |
REAL masque(iim + 1,jjm + 1) … CALL rugosite(dlon, dlat, champ, rlonv(:iim), rlatu, champint, & masque(:iim, :)) |
Appelé |
SUBROUTINE rugosite(imdep, jmdep, xdata, ydata, entree, . imar, jmar, x, y, sortie, mask) INTEGER imdep, jmdep REAL xdata(imdep),ydata(jmdep) REAL entree(imdep,jmdep) c INTEGER imar, jmar REAL x(imar),y(jmar) REAL sortie(imar,jmar), mask(imar,jmar) |
SUBROUTINE rugosite(xdata, ydata, entree, x, y, sortie, mask) REAL xdata(:),ydata(:) REAL entree(:,:) REAL x(:),y(:) REAL sortie(:,:) real, intent(in):: mask(:,:) |
Quelques remarques :
- Dans la version actuelle, on a dû recopier une section du tableau
masque
de profil(/iip1, jjp1/)
dans le tableaumask
de profil(/iim, jjp1/)
. Cette recopie est faite uniquement pour pouvoir passer la section de tableau àrugosite
. Cette recopie n'a pas lieu d'être si on transmet le profil des tableaux : on passe simplement la section de tableau. C'est un gain de clarté dans l'appelant. - En déclarant les arguments tableaux avec profil transmis, dans
l'appelé, rien n'empêche d'utiliser les étendues des tableaux en
déclarant des variables locales. Par exemple :
INTEGER imdep
…imdep = size(xdata)
Néanmoins, si on adopte le style de Fortran 95, on utilise des expressions entre tableaux au lieu de boucles sur les éléments. Les variables contenant les étendues des tableaux n'ont souvent plus lieu d'exister. - En déclarant les arguments tableaux avec profil transmis, dans
l'appelé, on peut faire des vérifications de cohérence sur les
étendues des tableaux transmis. Par exemple, voici une façon tirée de
Numerical Recipes. Au lieu de définir simplement
imdep
parsize(xdata)
comme ci-dessus, on écrit à la place :imdep = assert_eq(size(xdata), size(entree, 1), "rugosite")
Ce qui teste l'égalité desize(xdata)
etsize(entree, 1)
, donne une valeur àimdep
s'il y a égalité, et arrête le programme avec un message d'erreur sinon. - Si on déclare explicitement les étendues dans l'appelé, comme dans
la version actuelle, la cohérence est entièrement à la charge du
programmeur. Il ne peut y avoir aucun contrôle automatique à la
compilation ou à l'exécution. Tout est permis du côté de l'appelant :
on peut passer un tableau de rang quelconque, ne contenant pas assez
d'éléments, etc. Par exemple, si dans l'appelant
rlatu
était de taillejjm
et nonjjp1
, la compilation se passerait bien, aucune détection de l'erreur ne serait possible dansrugosite
. On aurait au mieux segmentation fault à l'exécution, au pire (sans les options de débogage) des résultats silencieusement faux. La transmission du profil est la méthode la plus sûre.
Cf. aussi CLM Coding Conventions.