Section courante

A propos

Section administrative du site

 Langage  Elément  Tutoriel  Programmation  IDE  Annexe  Aide 
ABAP/4
Ada
Assembleur
Assembly & bytecode
ASP (Active Server Pages)
Basic
C
C++
C# (C Sharp)
Cobol
ColdFusion
Fortran
HTML
Java
JavaScript
LISP
Logo
LotusScript
Oberon
Pascal
Perl
PHP
PL/1
Prolog
Python
Rebol
REXX
Ruby
Rust
SAS
NoSQL
SQL
Swift
X++ (Axapta)
GNAT
SMALLAda
VHDL
Assembleur 370
Assembleur 1802
Assembleur 4004
Assembleur 6502
Assembleur 6800
Assembleur 68000
Assembleur 8080 et 8085
Assembleur 8089
Assembleur 80x86
Assembleur AGC4
Assembleur ARM
Assembleur DPS 8000
Assembleur i860
Assembleur Itanium
Assembleur MIPS
Assembleur PDP-11
Assembleur PowerPC
Assembleur RISC-V
Assembleur SPARC
Assembleur SuperH
Assembleur UNIVAC I
Assembleur VAX
Assembleur Z80
Assembleur Z8000
Assembleur z/Architecture
ASSEMBLER/MONITOR 64
Micol Assembler
GFA Assembler
A86
MASM (Macro Assembler)
TASM (Turbo Assembler)
CIL
Jasmin
LLVM
MSIL
Parrot
P-Code (PCode)
SWEET16
G-Pascal
ASP 1.0
ASP 2.0
ASP 3.0
ASP.NET
ASP.NET Core
ABasiC (Amiga)
Adam SmartBASIC
Altair BASIC
AmigaBASIC (Amiga)
AMOS Basic (Amiga)
Atari Basic (Atari 400, 600 XL, 800, 800XL)
Basic Apple II (Integer BASIC/APPLESOFT)
Basic Commodore 64 (CBM-BASIC)
Basic Commodore 128 (BASIC 7.0)
Basic Commodore VIC-20 (CBM-BASIC 2.0)
Basic Coco 1 (Color Basic)
Basic Coco 2 (Extended Color Basic)
Basic Coco 3 (Extended Color Basic 2.0)
BASICA (PC DOS)
Basic Pro
BBC BASIC
Blitz BASIC (Amiga)
DarkBASIC
Dartmouth BASIC
GFA-Basic (Atari ST/Amiga)
GWBASIC (MS-DOS)
Liberty BASIC
Locomotive BASIC (Amstrad CPC)
MSX-Basic
Omikron Basic (Atari ST)
Oric Extended Basic
Power Basic
Quick Basic/QBasic (MS-DOS)
Sinclair BASIC (ZX80, ZX81, ZX Spectrum)
ST BASIC (Atari ST)
Turbo Basic
Vintage BASIC
VBScript
Visual Basic (VB)
Visual Basic .NET (VB .NET)
Visual Basic pour DOS
Yabasic
BeckerBASIC
SIMONS' BASIC
Basic09 d'OS-9
Disk Extended Color Basic
Basic09 d'OS-9
Disk Extended Color Basic
Access
Excel
Visual Basic pour Windows
Visual Basic .NET pour Windows
C Shell Unix (csh)
C pour Amiga
C pour Atari ST
C pour DOS
C pour Falcon030
C pour GEMDOS (Atari ST)
C pour Linux
C pour PowerTV OS
C pour OS/2
C pour Unix
C pour Windows
Aztec C
CoCo-C
GNU C
HiSoft C
IBM C/2
Introl-C
Lattice C
Microsoft C
MinGW C
MSX-C
Open Watcom C
OS-9 C Compiler
Pure C
Quick C
Turbo C
HiSoft C for Atari ST
HiSoft C for CP/M (Amstrad CPC)
C++ pour OS/2
C++ pour Windows
Borland C++
C++Builder
IBM VisualAge C++
Intel C++
MinGW C++
Open Watcom C++
Symantec C++
Turbo C++
Visual C++
Visual C++ .NET
Watcom C++
Zortech C++
C# (C Sharp) pour Windows
Apple III Cobol
Microsoft Cobol
BlueDragon
Lucee
OpenBD
Railo
Smith Project
Microsoft Fortran
WATFOR-77
CSS
FBML
Open Graph
SVG
XML
XSL/XSLT
LESS
SASS
GCJ (GNU)
JSP
Jython
Visual J++
Node.js
TypeScript
AutoLISP
ACSLogo
LotusScript pour Windows
Amiga Oberon
Oberon .NET
Apple Pascal
Delphi/Kylix/Lazarus
Free Pascal
GNU Pascal
HighSpeed Pascal
IBM Personal Computer Pascal
Lisa Pascal
Maxon Pascal
MPW Pascal
OS-9 Pascal
OSS Personal Pascal
Pascal-86
Pascal du Cray Research
Pascal/VS
Pascal-XT
PURE Pascal
QuickPascal
RemObjets Chrome
Sun Pascal
THINK Pascal
Tiny Pascal (TRS-80)
Turbo Pascal
UCSD Pascal
VAX Pascal
Virtual Pascal
Turbo Pascal for CP/M-80
Turbo Pascal for DOS
Turbo Pascal for Macintosh
Turbo Pascal for Windows
CodeIgniter (Cadre d'application)
Drupal (Projet)
Joomla! (Projet)
Phalanger (PHP .NET)
phpBB (Projet)
Smarty (balise)
Twig (balise)
Symfony (Cadre d'application)
WordPress (Projet)
Zend (Cadre d'application)
PL360
PL/M-80
PL/M-86
Turbo Prolog
CPython
IronPython
Jython
PyPy
AREXX
Regina REXX
JMP
Btrieve
Cassandra
Clipper
CouchDB
dBASE
Hbase
Hypertable
MongoDB
Redis
Access
BigQuery
DB2
H2
Interbase
MySQL
Oracle
PostgreSQL
SAP HANA
SQL Server
Sybase
U-SQL
Introduction
Les remarques
Les opérateurs
Les instruction conditionnelles
Les instructions de boucles
Type de données
Définition de fonction
Référence de mots réservés (mots clefs)
Référence de procédures et fonctions
Les modules (Packages)
Les premiers pas
Les éléments lexicaux
Les déclarations et types
Les noms et les expressions
Les instructions
Les sous-programmes
Les paquets
Les règles de visibilité
Les tâches
Structure du programme et problèmes de compilation
Les exceptions
Les unités génériques
Clauses de représentation et fonctionnalités dépendantes de la mise en oeuvre
Les entrées-sorties
Bonjour
Biochimie
Géographie
Géométrie
Histoire
Mathématique
Médicale
Météorologie
Océanographie
Sport
Temps
Trigonométrie
Validation
Calcul du calcium corrigé
Distance en Km entre deux longitudes et latitudes
Aire d'un cercle
Aire d'une surface de prisme rectangulaire
Aire d'un triangle
Distance entre deux points
Chiffre romain
Ackermann
Exp
Factoriel
Fibonacci
Log
Nombre premier
Odd
Random
Sqrt
Triangle Pascal
Hauteur utérine
Unité de mesure
Fréquence des vagues
Hockey
Année bissextile
Date de la Pâque
Atn/ATan/ArcTan
Courriel
AdaGIDE
GNAT Programming Studio
SET's Editor
Attributs de langages prédéfinis
Les pragma de langage prédéfinis
Environnement de langage prédéfini
Référence de termes et du vocabulaire
Téléchargement
Préface
Notes légal
Dictionnaire
Recherche

Structure du programme et problèmes de compilation

La structure générale des programmes et les fonctionnalités de compilation séparée sont décrites dans cette page. Un programme est un ensemble d'une ou plusieurs unités de compilation soumises à un compilateur dans une ou plusieurs compilations. Chaque unité de compilation spécifie la compilation séparée d'une construction pouvant être une déclaration ou un corps de sous-programme, une déclaration ou un corps de paquetage, une déclaration ou un corps générique ou une instanciation générique. Alternativement, cette construction peut être une sous-unité, auquel cas elle inclut le corps d'un sous-programme, d'un paquetage, d'une unité de tâche ou d'une unité générique déclarée dans une autre unité de compilation.

Unités de compilation - Unités de bibliothèque

Le texte d'un programme peut être soumis au compilateur en une ou plusieurs compilations. Chaque compilation est une succession d'unités de compilation.

compilation ::= {unite_de_compilation}
unite_de_compilation ::=
    clause_contextuelle unite_bibliotheque | clause_contextuelle unite_secondaire

unite_bibliotheque ::=
       declaration_sous-programme | declaration_de_paquet
     | declaration_generique | instantiation_generique
     | sous_programme_corps

unite_secondaire ::= unite_bibliotheque_corps | sous_unite

unite_bibliotheque_corps ::= sous_programme_corps | corps_du_paquet

Les unités de compilation d'un programme sont dites appartenir à une bibliothèque de programmes. Une unité de compilation définit soit une unité de bibliothèque, soit une unité secondaire. Une unité secondaire est soit le corps propre compilé séparément d'une unité de bibliothèque, soit une sous-unité d'une autre unité de compilation. Le désignateur d'un sous-programme compilé séparément (qu'il s'agisse d'une unité de bibliothèque ou d'une sous-unité) doit être un identifiant. Dans une bibliothèque de programmes, les noms simples de toutes les unités de bibliothèque doivent être des identifiants distincts.

L'effet de la compilation d'une unité de bibliothèque est de définir (ou de redéfinir) cette unité comme appartenant à la bibliothèque de programmes. Pour les règles de visibilité, chaque unité de bibliothèque agit comme une déclaration apparaissant immédiatement dans le paquet STANDARD.

L'effet de la compilation d'une unité secondaire est de définir le corps d'une unité de bibliothèque, ou dans le cas d'une sous-unité, de définir le corps propre d'une unité de programme qui est déclarée dans une autre unité de compilation.

Un corps de sous-programme donné dans une unité de compilation est interprété comme une unité secondaire si la bibliothèque de programmes contient déjà une unité de bibliothèque étant un sous-programme portant le même nom; dans le cas contraire, il est interprété à la fois comme une unité de bibliothèque et comme le corps de l'unité de bibliothèque correspondante (c'est-à-dire comme une unité secondaire).

Les unités de compilation d'une compilation sont compilées dans l'ordre donné. Un pragma s'appliquant à l'ensemble d'une compilation doit apparaître avant la première unité de compilation de cette compilation. Un sous-programme étant une unité de bibliothèque peut être utilisé comme programme principal au sens habituel. Chaque programme principal agit comme s'il était appelé par une tâche d'environnement; les moyens par lesquels cette exécution est initiée ne sont pas prescrits par la définition du langage. Une implémentation peut imposer certaines exigences sur les paramètres et sur le résultat, le cas échéant, d'un programme principal. Dans tous les cas, chaque implémentation doit autoriser, au moins, des programmes principaux qui sont des procédures sans paramètres, et chaque programme principal doit être un sous-programme qui est une unité de bibliothèque.

Remarques : Un programme simple peut être constitué d'une seule unité de compilation. Une compilation n'a pas besoin d'avoir d'unités de compilation ; par exemple, son texte peut être constitué de pragmas.

Le désignateur d'une fonction de bibliothèque ne peut pas être un symbole d'opérateur, mais une déclaration de renommage est autorisée pour renommer une fonction de bibliothèque en tant qu'opérateur. Deux sous-programmes de bibliothèque doivent avoir des noms simples distincts et ne peuvent donc pas se surcharger l'un l'autre. Cependant, les déclarations de renommage sont autorisées à définir des noms surchargés pour de tels sous-programmes, et un sous-programme déclaré localement est autorisé à surcharger un sous-programme de bibliothèque. Le nom étendu STANDARD.L peut être utilisé pour une unité de bibliothèque L (à moins que le nom STANDARD ne soit masqué) puisque les unités de bibliothèque agissent comme des déclarations qui se produisent immédiatement dans le paquet STANDARD.

Clauses de contexte - Clauses with

Une clause de contexte est utilisée pour spécifier les unités de bibliothèque dont les noms sont nécessaires dans une unité de compilation.

clause_contextuelle ::= {clause_with {clause_d_utilisation}}

clause_with ::= with nom_simple_de_l_unite {, nom_simple_de_l_unite};

Les noms apparaissant dans une clause de contexte doivent être les noms simples des unités de bibliothèque. Le nom simple de toute unité de bibliothèque est autorisé dans une clause with. Les seuls noms autorisés dans une clause use d'une clause context sont les noms simples des paquets de bibliothèque mentionnés par les clauses with précédentes de la clause context. Un nom simple déclaré par une déclaration de renommage n'est pas autorisé dans une clause context.

Les clauses with et use de la clause context d'une unité de bibliothèque s'appliquent à cette unité de bibliothèque et également à l'unité secondaire définissant le corps correspondant (qu'une telle clause soit répétée ou non pour cette unité). De même, les clauses with et use de la clause context d'une unité de compilation s'appliquent à cette unité et également à ses sous-unités, le cas échéant.

Si une unité de bibliothèque est nommée par une clause with s'appliquant à une unité de compilation, alors cette unité de bibliothèque est directement visible dans l'unité de compilation, sauf si elle est masquée ; l'unité de bibliothèque est visible comme si elle était déclarée immédiatement dans le paquet STANDARD.

Les dépendances entre les unités de compilation sont définies par des clauses with; c'est-à-dire qu'une unité de compilation mentionnant d'autres unités de bibliothèque dans ses clauses with dépend de ces unités de bibliothèque. Ces dépendances entre unités sont prises en compte pour la détermination de l'ordre autorisé de compilation (et de recompilation) des unités de compilation, et pour la détermination de l'ordre autorisé d'élaboration des unités de compilation.

Remarques : Une unité de bibliothèque nommée par une clause with d'une unité de compilation est visible (sauf si elle est masquée) dans l'unité de compilation et peut donc être utilisée comme unité de programme correspondante. Ainsi, dans l'unité de compilation, le nom d'un paquet de bibliothèque peut être donné dans les clauses use et peut être utilisé pour former des noms étendus; un sous-programme de bibliothèque peut être appelé ; et des instances d'une unité générique de bibliothèque peuvent être déclarées.

Les règles données pour les clauses with sont telles que le même effet est obtenu que le nom d'une unité de bibliothèque soit mentionné une ou plusieurs fois par les clauses with applicables, ou même dans une clause with donnée.

Exemple 1 : Un programme principal : Voici un exemple de programme principal constitué d'une seule unité de compilation : une procédure d'impression des racines réelles d'une équation quadratique. Le paquet prédéfini TEXT_IO et un paquet défini par l'utilisateur REAL.OPERATIONS (contenant la définition du type REAL et des paquets REAL_IO et REAL_FUNCTIONS) sont supposés déjà présents dans la bibliothèque de programmes. De tels paquets peuvent être utilisés par d'autres programmes principaux.

  1. with TEXT_IO, REAL_OPERATIONS; use REAL_OPERATIONS;
  2. procedure QUADRATIC_EQUATION is
  3.   A, B, C, D : REAL;
  4.   use REAL_IO,          -- permet d'obtenir une visibilité directe de GET et PUT pour REAL
  5.       TEXT_IO,          -- permet d'obtenir une visibilité directe de PUT pour les chaînes et de NEW_LINE
  6.       REAL_FUNCTIONS;   -- permet d'obtenir une visibilité directe de SORT
  7. begin
  8.  GET(A); GET(B); GET(C);
  9.  D := B**2 - 4.0*A*C;
  10.  if D < 0.0 then
  11.   PUT("Racines imaginaires.");
  12.  else
  13.   PUT("Racines réelles : X1 = ");
  14.   PUT((-B - SQRT(D))/(2.Q*A)); PUT(" X2 = ");
  15.   PUT((-B + SQRT(D))/(2.0*A));
  16.  end if;
  17.  NEW_LINE;
  18. end QUADRATIC_EQUATION;

Notes sur l'exemple : Les clauses with d'une unité de compilation ne doivent mentionner que les noms des sous-programmes et paquets de bibliothèque dont la visibilité est réellement nécessaire au sein de l'unité. Elles n'ont pas besoin (et ne devraient pas) mentionner d'autres unités de bibliothèque étant utilisées à leur tour par certaines des unités nommées dans les clauses with, à moins que ces autres unités de bibliothèque ne soient également utilisées directement par l'unité de compilation actuelle. Par exemple, le corps du paquet REAL_OPERATIONS peut nécessiter des opérations élémentaires fournies par d'autres paquets. Ces derniers paquets ne doivent pas être nommés par la clause with de QUADRATIC_EQUATION puisque ces opérations élémentaires ne sont pas directement appelées au sein de son corps.

Exemples d'unités de compilation

Une unité de compilation peut être divisée en plusieurs unités de compilation. Prenons par exemple le programme suivant :

  1. procedure PROCESSOR is
  2.  
  3.   SMALL : constant := 20;
  4.   TOTAL : INTEGER  := 0;
  5.   
  6.   package STOCK is
  7.     LIMIT : constant := 1000;
  8.     TABLE : array (1 .. LIMIT) of INTEGER;
  9.     procedure RESTART;
  10.   end STOCK;
  11.  
  12.   package body STOCK is
  13.     procedure RESTART is begin
  14.       for N in 1 .. LIMIT loop
  15.         TABLE(N) := N;
  16.       end loop;
  17.     end;
  18.   begin
  19.     RESTART;
  20.   end STOCK;
  21.   
  22.   procedure UPDATE(X : INTEGER) is
  23.     use STOCK;
  24.   begin
  25.     ...
  26.     TABLE(X) := TABLE(X) + SMALL;
  27.      ...
  28.   end UPDATE;
  29.  
  30. begin
  31.   ...
  32.   STOCK.RESTART; -- réinitialise TABLE
  33.   ...
  34. end PROCESSOR;

Les trois unités de compilation suivantes définissent un programme avec un effet équivalent à l'exemple ci-dessus (les lignes brisées entre les unités de compilation servent à rappeler au lecteur que ces unités ne doivent pas nécessairement être des textes contigus).

Exemple 2 : Plusieurs unités de compilation :

  1. package STOCK is
  2.   LIMIT : constant := 1000;
  3.   TABLE : array (1 .. LIMIT) of INTEGER;
  4.   procedure RESTART;
  5. end STOCK;
  6.  
  7. ----------------------------
  8.  
  9. package body STOCK is
  10.   procedure RESTART is
  11.   begin
  12.     for N in 1 .. LIMIT loop
  13.        TABLE(N) := N;
  14.     end loop;
  15.   end;
  16. begin
  17.   RESTART;
  18. end STOCK;
  19.  
  20. ----------------------------
  21.  
  22. with STOCK;
  23. procedure PROCESSOR is
  24.  
  25.   SMALL : constant := 20;
  26.   TOTAL : INTEGER  := 0;
  27.  
  28.   procedure UPDATE(X ; INTEGER) is
  29.     use STOCK;
  30.   begin
  31.      ...
  32.      TABLE(X) := TABLE(X) + SMALL;
  33.       ...
  34.   end UPDATE;
  35. begin
  36.   STOCK.RESTART; -- réinitialise TABLE
  37. end PROCESSOR;

Notez que dans cette dernière version, le paquet STOCK n'a aucune visibilité sur les identifiants externes autres que les identifiants prédéfinis (du paquet STANDARD). En particulier, STOCK n'utilise aucun identifiant déclaré dans PROCESSOR tel que SMALL ou TOTAL ; sinon STOCK n'aurait pas pu être extrait de PROCESSOR de la manière ci-dessus. La procédure PROCESSOR, en revanche, dépend de STOCK et mentionne ce paquet dans une clause with. Cela permet les occurrences internes de STOCK dans le nom étendu STOCK .RESTART et dans la clause use.

Ces trois unités de compilation peuvent être soumises dans une ou plusieurs compilations. Par exemple, il est possible de soumettre la spécification du paquet et le corps du paquet ensemble et dans cet ordre dans une seule compilation.

Sous-unités des unités de compilation

Une sous-unité est utilisée pour la compilation séparée du corps propre d'une unité de programme déclarée dans une autre unité de compilation. Cette méthode de division d'un programme permet un développement de programme hiérarchique :

corps_stub ::=
    specification_du_sous_programme is separate;
  | package body nom_simple_du_paquet is separate;
  | task body tache_simple_nom is separate;

sous_unite ::=
      separate (nom_unite_parent) corps_propre

Un stub de corps n'est autorisé comme corps d'une unité de programme (un sous-programme, un paquet, une unité de tâche ou une unité générique) que si le stub de corps apparaît immédiatement dans la spécification d'un paquet de bibliothèque ou dans la partie déclarative d'une autre unité de compilation.

Si le corps d'une unité de programme est un stub de corps, une sous-unité compilée séparément contenant le corps approprié correspondant est requise. Dans le cas d'un sous-programme, les spécifications de sous-programme données dans le corps approprié et dans le stub de corps doivent être conformes.

Chaque sous-unité mentionne le nom de son unité parente, c'est-à-dire l'unité de compilation où le stub de corps correspondant est donné. Si l'unité parente est une unité de bibliothèque, elle est appelée unité de bibliothèque ancêtre. Si l'unité parente est elle-même une sous-unité, le nom de l'unité parente doit être donné en entier sous forme de nom développé, en commençant par le nom simple de l'unité de bibliothèque ancêtre. Les noms simples de toutes les sous-unités ayant la même unité de bibliothèque ancêtre doivent être des identifiants distincts.

La visibilité au sein du corps propre d'une sous-unité est la visibilité étant obtenue à la place du corps correspondant (au sein de l'unité parente) si les clauses with et use de la sous-unité étaient ajoutées à la clause context de l'unité parente. Si l'unité parente est elle-même une sous-unité, la même règle est alors utilisée pour définir la visibilité au sein du corps propre de l'unité parente.

L'élaboration d'un corps de référence a pour effet d'élaborer le corps propre de la sous-unité.

Remarques : Deux sous-unités de différentes unités de bibliothèque dans la même bibliothèque de programmes n'ont pas besoin d'avoir des identifiants distincts. Dans tous les cas, leurs noms complets développés sont distincts, car les noms simples des unités de bibliothèque sont distincts et les noms simples de toutes les sous-unités qui ont une unité de bibliothèque donnée comme unité ancêtre sont également distincts. Au moyen de déclarations de renommage, des noms de sous-programmes surchargés qui renomment des sous-unités (distinctes) peuvent être introduits.

Une unité de bibliothèque nommée par la clause with d'une sous-unité peut être masquée par une déclaration (avec le même identifiant) donnée dans le corps propre de la sous-unité. De plus, une telle unité de bibliothèque peut même être masquée par une déclaration donnée dans une unité parente puisqu'une unité de bibliothèque agit comme si elle était déclarée dans STANDARD ; cela n'affecte cependant pas l'interprétation des clauses with elles-mêmes, car seuls les noms des unités de bibliothèque peuvent apparaître dans les clauses with.

Exemples de sous-unités

La procédure TOP est d'abord écrite comme une unité de compilation sans sous-unités :

  1. with TEXT_IO;
  2. procedure TOP is
  3.  
  4.   type REAL is digits 10;
  5.   R, S : REAL := 1.0;
  6.   
  7.   package FACILITY is
  8.     PI : constant 3.14159_26536;
  9.     function  F (X : REAL) return REAL;
  10.     procedure G (Y, Z : REAL);
  11.   end FACILITY;
  12.  
  13.   package body FACILITY is
  14.     -- quelques déclarations locales suivies de
  15.  
  16.     function F(X : REAL) return REAL is
  17.     begin
  18.       -- séquence d'instructions de F
  19.     end F;
  20.  
  21.     procedure G(Y, Z : REAL) is
  22.       -- procédures locales utilisant TEXT_IO
  23.        ...
  24.     begin
  25.       -- séquence d'instructions de G
  26.     end G;
  27.   end FACILITY;
  28.  
  29.   procedure TRANSFORM(U : in out REAL) is
  30.     use FACILITY;
  31.   begin
  32.     U := F(U);
  33.      ...
  34.   end TRANSFORM;
  35. begin -- TOP
  36.   TRANSFORM(R);
  37.   ...
  38.   FACILITY.G(R, S);
  39. end TOP;

Le corps du paquet FACILITY et celui de la procédure TRANSFORM peuvent être transformés en sous-unités séparées de TOP. De même, le corps de la procédure G peut être transformé en sous-unité de FACILITY comme suit.

Exemple 3 :

  1. procedure TOP is
  2.  
  3.   type REAL is digits 10;
  4.   R, S : REAL := 1.0;
  5.  
  6.   package FACILITY is
  7.     PI : constant := 3.14159_26536;
  8.     function F (X : REAL) return REAL;
  9.     procedure G (Y, Z : REAL);
  10.   end FACILITY;
  11.   
  12.   package body FACILITY is separate;                 -- bout de FACILITY
  13.   procedure TRANSFORMS(U : in out REAL) is separate; -- bout de TRANSFORM
  14.   
  15. begin -- TOP
  16.   TRANSFORM(R);
  17.   ...
  18.   FACILITY.G(R, S);
  19. end TOP;
  20. ---------------------------
  21.  
  22. separate (TOP)
  23. procedure TRANSFORM(U : in out REAL) is
  24.   use FACILITY;
  25. begin
  26.   U := F(U);
  27.   ...
  28. end TRANSFORM;
  29.  
  30. ---------------------------
  31.  
  32. separate (TOP)
  33. package body FACILITY is
  34.   -- quelques déclarations locales suivies de
  35.   
  36.   function F(X : REAL) return REAL is
  37.   begin
  38.     -- séquence d'instructions de F
  39.   end F;
  40.   
  41.   procedure G(Y, Z : REAL) is separate; -- bout de G
  42. end FACILITY;     
  43.  
  44. ---------------------------
  45.  
  46. with TEXT_IO;
  47. separate (TOP.FACILITY) - full name of FACILITY
  48. procedure G(Y, Z : REAL) is
  49.   -- procédures locales utilisant TEXT_IO
  50.   ...
  51. begin
  52.   -- séquence d'instructions de G
  53.   ...
  54. end G;

Dans l'exemple ci-dessus, TRANSFORM et FACILITY sont des sous-unités de TOP, et G est une sous-unité de FACILITY. La visibilité dans la version divisée est la même que dans la version initiale, à l'exception d'un changement : comme TEXT_IO n'est utilisé que dans G, la clause with correspondante est écrite pour G au lieu de TOP. Hormis ce changement, les mêmes identifiants sont visibles aux points de programme correspondants dans les deux versions. Par exemple, tous les éléments suivants sont (directement) visibles dans le corps propre de la sous-unité G : la procédure TOP, le type REAL, les variables R et S, le paquet FACILITY et le numéro nommé PI contenu et les sous-programmes F et G.

Ordre de compilation

Les règles définissant l'ordre dans lequel les unités peuvent être compilées sont des conséquences directes des règles de visibilité et, en particulier, du fait que toute unité de bibliothèque mentionnée par la clause de contexte d'une unité de compilation est visible dans l'unité de compilation.

Une unité de compilation doit être compilée après toutes les unités de bibliothèque nommées par sa clause de contexte. Une unité secondaire étant un sous-programme ou un corps de paquet doit être compilée après l'unité de bibliothèque correspondante. Toute sous-unité d'une unité de compilation parent doit être compilée après l'unité de compilation parent. Si une erreur est détectée lors de la tentative de compilation d'une unité de compilation, la tentative de compilation est rejetée et n'a aucun effet sur la bibliothèque du programme ; il en va de même pour les recompilations (aucune unité de compilation ne peut devenir obsolète à cause d'une telle recompilation).

L'ordre dans lequel les unités de compilation d'un programme sont compilées doit être cohérent avec l'ordre partiel défini par les règles ci-dessus.

Des règles similaires s'appliquent aux recompilations. Une unité de compilation est potentiellement affectée par un changement dans toute unité de bibliothèque nommée par sa clause de contexte. Une unité secondaire est potentiellement affectée par un changement dans l'unité de bibliothèque correspondante. Les sous-unités d'une unité de compilation parent sont potentiellement affectées par un changement de l'unité de compilation parent. Si une unité de compilation est recompilée avec succès, les unités de compilation potentiellement affectées par ce changement sont obsolètes et doivent être recompilées à moins qu'elles ne soient plus nécessaires. Une implémentation peut être en mesure de réduire les coûts de compilation si elle peut déduire que certaines des unités potentiellement affectées ne sont pas réellement affectées par le changement.

Les sous-unités d'une unité peuvent être recompilées sans affecter l'unité elle-même. De même, les modifications apportées à un sous-programme ou au corps d'un paquet n'affectent pas les autres unités de compilation (à l'exception des sous-unités du corps) puisque ces unités de compilation n'ont accès qu'au sous-programme ou à la spécification du paquet. Une implémentation n'est autorisée à déroger à cette règle que pour les inclusions en ligne, pour certaines optimisations du compilateur et pour certaines implémentations d'unités de programme génériques, comme décrit ci-dessous.

Exemples d'ordre de compilation :

  1. Dans l'exemple 1 : la procédure QUADRATIC_EQUATION doit être compilée après les paquetages de bibliothèque TEXT_IO et REAL_OPERATIONS puisqu'ils apparaissent dans sa clause with.
  2. Dans l'exemple 2 : le corps du paquetage STOCK doit être compilé après la spécification du paquetage correspondant.
  3. Dans l'exemple 2 : la spécification du paquet STOCK doit être compilée avant la procédure PROCESSOR. D'autre part, la procédure PROCESSOR peut être compilée avant ou après le corps du paquet STOCK.
  4. Dans l'exemple 3 : la procédure G doit être compilée après le paquet TEXT_IO puisque ce paquet est nommé par la clause with de G. D'autre part, TEXT_IO peut être compilé avant ou après TOP.
  5. Dans l'exemple 3 : les sous-unités TRANSFORM et FACILITY doivent être compilées après le programme principal TOP. De même, la sous-unité G doit être compilée après son unité parente FACILITY.

Remarques : Pour les paquets de bibliothèque, il résulte des règles de recompilation qu'un corps de paquet est rendu obsolète par la recompilation de la spécification correspondante. Si la nouvelle spécification de paquet est telle qu'un corps de paquet n'est pas nécessaire (c'est-à-dire si la spécification de paquet ne contient pas la déclaration d'une unité de programme), alors la recompilation d'un corps pour ce paquet n'est pas nécessaire. Dans tous les cas, le corps de paquet obsolète ne doit pas être utilisé et peut donc être supprimé de la bibliothèque de programmes.

La bibliothèque de programmes

Les compilateurs doivent appliquer les règles du langage de la même manière pour un programme constitué de plusieurs unités de compilation (et sous-unités) que pour un programme soumis sous forme de compilation unique. Par conséquent, un fichier de bibliothèque contenant des informations sur les unités de compilation de la bibliothèque de programmes doit être maintenu par le compilateur ou l'environnement de compilation. Ces informations peuvent inclure des tables de symboles et d'autres informations relatives à l'ordre des compilations précédentes.

Une soumission normale au compilateur comprend les unités de compilation et le fichier de bibliothèque. Ce dernier est utilisé pour les contrôles et est mis à jour pour chaque unité de compilation compilée avec succès.

Remarques : une seule bibliothèque de programmes est implicite pour les unités de compilation d'une compilation. L'existence possible de différentes bibliothèques de programmes et les moyens par lesquels elles sont nommées ne sont pas des préoccupations de la définition du langage ; elles sont des préoccupations de l'environnement de programmation.

Il devrait y avoir des commandes pour créer la bibliothèque de programmes d'un programme donné ou d'une famille de programmes donnée. Ces commandes peuvent permettre la réutilisation d'unités d'autres bibliothèques de programmes. Enfin, il devrait y avoir des commandes pour interroger l'état des unités d'une bibliothèque de programmes. La forme de ces commandes n'est pas spécifiée par la définition du langage.

Élaboration des unités de bibliothèque

Avant l'exécution d'un programme principal, toutes les unités de bibliothèque nécessaires au programme principal sont élaborées, ainsi que les corps d'unités de bibliothèque correspondants, s'il y en a. Les unités de bibliothèque nécessaires au programme principal sont : celles nommées par des clauses with applicables au programme principal, à son corps et à ses sous-unités; celles nommées par des clauses with applicables à ces unités de bibliothèque elles-mêmes, aux corps d'unités de bibliothèque correspondants et à leurs sous-unités ; et ainsi de suite, de manière transitive. L'élaboration de ces unités de bibliothèque et des corps d'unités de bibliothèque correspondants est effectuée dans un ordre cohérent avec l'ordre partiel défini par les clauses with. De plus, une unité de bibliothèque mentionnée par la clause de contexte d'une sous-unité doit être élaborée avant le corps de l'unité de bibliothèque ancêtre de la sous-unité.

Un ordre d'élaboration cohérent avec cet ordre partiel ne garantit pas toujours que chaque corps d'unité de bibliothèque soit élaboré avant toute autre unité de compilation dont l'élaboration nécessite que le corps d'unité de bibliothèque soit déjà élaboré. Si l'élaboration préalable des corps d'unités de bibliothèque est nécessaire, cela peut être demandé par un pragma ELABORATE. La forme de ce pragma est la suivante :

pragma ELABORATE (nom_simple_de_l_unité_de_bibliotheque |, nom_simple_de_l_unité_de_bibliotheque});

Ces pragmes ne sont autorisés qu'immédiatement après la clause de contexte d'une unité de compilation (avant l'unité de bibliothèque suivante ou l'unité secondaire). Chaque argument d'un tel pragma doit être le nom simple d'une unité de bibliothèque mentionnée par la clause de contexte, et cette unité de bibliothèque doit avoir un corps d'unité de bibliothèque. Un tel pragma spécifie que le corps de l'unité de bibliothèque doit être élaboré avant l'unité de compilation donnée. Si l'unité de compilation donnée est une sous-unité, le corps de l'unité de bibliothèque doit être élaboré avant le corps de l'unité de bibliothèque ancêtre de la sous-unité.

Le programme est illégal si aucun ordre cohérent ne peut être trouvé (c'est-à-dire si une circularité existe). L'élaboration des unités de compilation du programme est effectuée dans un ordre n'étant pas défini par ailleurs par le langage.

Optimisation du programme

L'optimisation de l'élaboration des déclarations et de l'exécution des instructions peut être effectuée par les compilateurs. En particulier, un compilateur peut être capable d'optimiser un programme en évaluant certaines expressions, en plus de celles qui sont des expressions statiques. Si l'une de ces expressions, statique ou non, est telle qu'une exception serait levée par son évaluation, alors le code dans ce chemin du programme peut être remplacé par du code pour lever l'exception ; il en va de même pour les exceptions levées par l'évaluation des noms et des expressions simples.

Un compilateur peut constater que certaines instructions ou sous-programmes ne seront jamais exécutés, par exemple, si leur exécution dépend d'une condition connue pour être FALSE. Le code machine objet correspondant peut alors être omis. Cette règle permet l'effet de compilation conditionnelle au sein du langage.

Remarque : une expression dont l'évaluation est connue pour lever une exception ne doit pas nécessairement représenter une erreur si elle se produit dans une instruction ou un sous-programme n'étant jamais exécuté. Le compilateur peut avertir le programmeur d'une erreur potentielle.



PARTAGER CETTE PAGE SUR
Dernière mise à jour : Mardi, le 7 janvier 2025