2 votes

Qu'est-ce qui se passe réellement en mémoire dans les blocs communs Fortran ?

Je suis passé de C à Fortran avec une solide base en C. Tout est assez simple, sauf les mécanismes réels de fonctionnement des blocs communs me laissent perplexe, et je ne trouve aucun endroit qui les décrit en détail.

Disons que j'ai le bloc commun suivant :

COMMON/MYBLOCK/ A,B,C

D'après ce que je comprends, cela va mettre de côté un morceau de mémoire qui contient trois...choses, qui ne sont pas vraiment associées aux noms dans le bloc, et en fait si j'ai le code suivant plus tard dans ma source :

SUBROUTINE MYSUB(...)
...
COMMON/MYBLOCK/ X,Y,Z
...
END 

Alors maintenant X est associé à ce qui était autrefois A, et pareillement Y à B et Z à C.

Donc cela signifie que COMMON/MYBLOCK/ est... un tableau de pointeurs nuls lorsqu'il est déclaré ? Il n'y a pas de type associé à aucun de ces pointeurs, donc... la mémoire est allouée lorsqu'une valeur est assignée ? Que se passe-t-il si je dis A='A' dans mon thread principal, puis dans MYSUB je dis A=3.141592 ? Si j'ai une subroutine que je veux retourner une valeur dans A par référence (car elle fait partie d'une bibliothèque externe), puis-je simplement dire CALL MYSUB2(A) et compter sur le compilateur pour s'en charger ? Ou dois-je appeler MYSUB2 sur une variable locale d'abord, puis l'assigner à A ?

C'est bizarre, Fortran est un langage si fortement typé partout ailleurs, mais les blocs communs sont juste comme "fais ce que tu veux, mec, nous ne faisons pas de types ici"...

0 votes

Pourquoi voulez-vous utiliser common? Ils ne devraient pas avoir été utilisés dans un nouveau code depuis 3 décennies. Utilisez des modules si vous devez vraiment avoir un état global et oubliez que vous avez déjà vu common - vous dormirez mieux pour cela. Ou regardez-vous un vieux code?

0 votes

Vous voulez dire qu'il y a des programmeurs en C qui travaillent sur du FORTRAN pour autre chose que du code hérité vieux de 30 ans ? Plus sérieusement, j'ai un vieux code hérité avec du COMMON partout, et j'essaie de comprendre ce qu'il fait en interne.

0 votes

Obtenez une copie de l'avant-projet du standard Fortran 2018 (recherchez N2146.pdf). Lisez la section 8.10 sur l'association de l'espace de stockage. Si vous avez un ancien code qui contient beaucoup de blocs COMMON, il utilise probablement des instructions EQUIVALENCE. Quoi qu'il en soit, la section 8.10.2.1 commence par La déclaration COMMON spécifie des blocs de stockage physique, appelés blocs communs, qui peuvent être accessibles par l'une des unités de portée dans un programme. Ainsi, la déclaration COMMON fournit un dispositif de données global basé sur l'association de l'espace de stockage (19.5.3).

3voto

Vladimir F Points 12375

Ne confondez pas ce que le langage standard vous permet et ce que vous pouvez obtenir avec les compilateurs existants et ce que les gens utilisent dans divers codes hérités.

Les blocs communs sont un endroit pour un stockage statique qui peut être accédé depuis diverses unités de compilation. Les variables stockées sont accessibles en utilisant le nom du bloc commun et la position (décalage) de la variable à l'intérieur du bloc commun.

Que les blocs communs se retrouvent dans le segment .data ou dans le segment .bss est un détail d'implémentation pour une plateforme particulière. Mais en pratique, sur les plateformes courantes aujourd'hui, les blocs communs apparaîtront dans l'un de ces segments.

Ce n'est pas là pour le jeu de types. On ne peut pas référencer la même adresse mémoire avec des types différents. Elle doit toujours être accédée en tant qu'un seul type. Vous pouvez vous en sortir en utilisant la même adresse mémoire avec des types différents uniquement si vous séparez les utilisations. Vous ne pouvez pas écrire un réel et lire un entier.

Les variables stockées dans les blocs communs ont certainement un type. Le type peut être déclaré explicitement ou déterminé en utilisant les règles de typage implicite.

 IMPLICITE NONE

 COMMON /BLOCK1/ A, B, C

 END

vous donnera

> gfortran common.f90 
common.f90:3:18:

  COMMON /BLOCK1/ A, B, C
                  1
Erreur : Le symbole ‘a’ à (1) n'a pas de type IMPLICITE
common.f90:3:21:

  COMMON /BLOCK1/ A, B, C
                     1
Erreur : Le symbole ‘b’ à (1) n'a pas de type IMPLICITE
common.f90:3:24:

  COMMON /BLOCK1/ A, B, C
                        1
Erreur : Le symbole ‘c’ à (1) n'a pas de type IMPLICITE

et vous devrez déclarer explicitement le type des variables.

Sans voir plus de votre code, nous devons conclure que vos variables sont de type réel selon les règles de typage implicite, à moins qu'une instruction IMPLICITE explicite n'impose des règles de typage implicite différentes.

0 votes

Cela n'a pas vraiment répondu à ma question, mais après quelques recherches sur Google, j'ai compris que IMPLICIT NONE indique essentiellement à Fortran de ne pas définir par défaut chaque variable sans type explicite en REAL ou INT en fonction du nom ? Ainsi, ce qui se passe réellement dans mon code ci-dessus est que A, B et C sont instanciés en REAL sans directive IMPLICIT NONE ?

0 votes

Pas de IMPLICIT NONE, et les règles de typage implicite s'appliquent. Les variables A, B et C sont alors des variables de type réel par défaut. Sur le matériel courant actuel, chacune occupe probablement 4 unités de stockage.

0 votes

J'ai ajouté une brève explication de ce qu'est réellement un bloc commun, mais il semblait de votre question que vous le saviez et vous vous demandiez seulement pourquoi ces variables ne possèdent aucun type.

0voto

Stefano Points 1

Les choses peuvent être plus compliquées... La première occurrence du bloc nommé définira la taille totale de la mémoire allouée au bloc nommé, mais lorsqu'il est référencé, on peut changer les noms des variables, leur ordre et leur type. La routine accèdera à la mémoire et assignera les valeurs correspondantes aux variables. Cela est sujet aux erreurs, mais était utilisé dans d'anciens codes pour optimiser (minimiser) l'utilisation de la mémoire.

COMMON /BLOCK1/ A(3)

équivaut à

COMMON /BLOCK1/ A, B, C

ou

COMMON /BLOCK1/ X, Y, Z

et le compilateur peut également accepter

COMMON /BLOCK1/ A, B, I1, I2

où des types réels et entiers implicites sont utilisés.

Une confusion supplémentaire peut survenir lorsque le bloc nommé est référencé plus d'une fois dans la même routine, mais il s'agit simplement d'une continuation de la liste de variables. Voir le guide de référence du compilateur Fortran d'Intel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X