• Aucun résultat trouvé

Un sous-type (subtype) permet d’appliquer une contrainte (constraint) à un type appelé type de base. Cette contrainte peut prendre différentes formes selon que le type de base est discret, réel ou autre. Pour l’instant, l’une des formes les plus utilisées, nécessaire pour les notions à venir est la contrainte d’intervalle, applicable à tout type discret [ARM 3.2]. Elle consiste à restreindre l’ensemble des valeurs possibles d’un tel type (valeurs qui forment en fait déjà un intervalle) en un intervalle plus petit (exemple 6.1).

Un intervalle (range) s’écrit en respectant l’une des trois formes suivantes:

borne_inf .. borne_sup identificateur_de_type_ou_sous_type attribut_range

• borne_inf et borne_sup sont des expressions d’un type de base discret; • identificateur_de_type_ou_sous_type d’un type de base égale-

ment discret ;

• attribut_range sera introduit plus loin (§ 8.2.7). Exemple 6.1 Exemples d’intervalles.

0..9valeurs entières de 0 à 9, le type de base est Integer;

Lundi..Vendredivaleurs énumérées de Lundi à Vendredi, le type de base est T_Jours_De_La_Semaine (§ 5.2.2);

'A'..'Z'lettres majuscules, le type de base est Character;

Integer'First..–1nombres entiers négatifs, le type de base est Integer;

I..J – 1nombres entiers de I à J–1, le type de base est un type entier (celui de I et J) avec le fait que, si I >= J, l’intervalle est vide;

Val_1..Val_2les valeurs de Val_1 à Val_2, le type de base peut être n’importe quel type discret;

Characterl’intervalle des 256 valeurs du type prédéfini Character (§

3.8.1);

T_Jours_De_La_Semainel’intervalle des 7 valeurs (noms des jours) du type

T_Jours_De_La_Semaine (§ 5.2.2).

Une contrainte d’intervalle (sur un type discret) a la forme suivante:

range intervalle

• range est un nouveau mot réservé;

SOUS-TYPES 130

(identificateur_de_type_ou_sous_type est ici interdit).

Il est maintenant possible de donner la forme générale de la déclaration d’un sous-type d’un type discret par le diagramme syntaxique de la figure 6.1.

Figure 6.1 Diagramme syntaxique définissant un sous-type discret.

Exemple 6.2 Déclarations de sous-types de types discrets. subtype T_Chiffre is Integer range 0 .. 9;

subtype T_Jours_Travail is T_Jours_De_La_Semaine range Lundi..Vendredi; subtype T_Majuscules is Character range 'A'..'Z';

subtype T_Negatifs is Integer range Integer'First .. –1;

subtype T_Dynamique is Integer range 1 .. Max;-- Max, variable

-- entiere

subtype T_Entiers is Integer;

Les deux dernières déclarations de l’exemple 6.2 nécessitent des explications complémentaires. Le sous-type T_Dynamique obtient la borne supérieure par la valeur de la variable Max. Cette valeur est donc fournie à l’exécution et non à la compilation. Il faut donc s’assurer que Max ait une valeur bien définie avant la déclaration de T_Dynamique. De plus le sous-type T_Entiers, comme aucune contrainte n’est donnée, est en fait un synonyme d’Integer. Cette façon de faire peut être utilisée pour surnommer n’importe quel type. Il existe des situations, en relation avec l’utilisation de paquetages (sect. 10.5), où un tel surnommage est pratique pour changer le nom d’un type exporté.

6.1.2 Utilisation et utilité des sous-types

Un sous-type n’introduit donc pas un nouveau type mais permet de restreindre les valeurs utilisables d’un type. Un identificateur de sous-type peut être utilisé, en

Déclaration de sous-type discret

Type_de_base subtype Identificateur is

Contrainte

;

SOUS-TYPES 131

général, là où un identificateur de type est permis. Exemple 6.3 Utilisation de sous-types de l’exemple 6.2.

Chiffre : T_Chiffre;variable dont les valeurs doivent se situer entre 0 et

9;

Jour : T_Jours_Travail;variable dont les valeurs doivent se situer entre

Lundi et Vendredi;

T_Jours_Travail'Firstattribut de valeur Lundi;

T_Jours_Travail'Lastattribut de valeur Vendredi;

procedure P (Lettre : in T_Majuscules);Le paramètre effectif devra être une lettre majuscule.

L’attribution d’une valeur à un objet dont la déclaration comporte une contrainte, donnée par un sous-type par exemple, est autorisée si la valeur respecte la contrainte (exemple 6.4). Dans le cas contraire, une erreur (l’exception Constraint_Error, sect. 6.3) est générée à l’exécution du programme.

Exemple 6.4 Attribution de valeurs à des objets dont la déclaration comporte une contrainte.

Chiffre : T_Chiffre;deux variables contraintes par un sous-type; Jour : T_Jours_Travail;

Nombre : Integer;une variable de type Integer;

Lettre : Character;une variable de type Character;

...

Jour := Mercredi;toujours correct; Nombre := Chiffre;toujours correct;

Chiffre := Nombre;correct si la valeur de Nombre est entre 0 et 9, une erreur est générée dans le cas contraire;

Jour := Samedi;erreur générée, Samedi n’est pas jour de travail;

P ( 'A' );toujours correct (P est declarée dans l’exemple 6.3);

P ( Lettre );correct si la valeur de Lettre est une majuscule, une erreur est générée dans le cas contraire.

Le principal intérêt des sous-types réside dans le fait que leur utilisation permet la détection d’erreurs à l’exécution (note 6.1), lorsque des valeurs inappropriées sont attribuées à un objet (affectation à une variable, passage en paramètre, etc.).

SOUS-TYPES 132

Il faut toujours avoir à l’esprit qu’un programme qui produit des résultats faux est plus difficile à corriger qu’un programme qui se termine brutalement par une erreur, surtout si l’apparition de l’erreur donne des indications précises sur l’endroit erroné du programme. L’arrivée d’erreurs, aussi frustrantes soient-elles, doit donc être considérée comme un symptôme moins grave que la production de résultats incertains.

Les sous-types imposent donc au programmeur une réflexion plus approfondie dans le choix des valeurs pour des variables et permettent la vérification à l’exécution des contraintes sur ces variables. Il faut préciser que cette vérification est effectuée par du code adéquat généré par le compilateur.

6.1.3 Sous-types prédéfinis

Il n’existe que deux sous-types prédéfinis dont la déclaration est la suivante: subtype Natural is Integer range 0 .. Integer'Last;

subtype Positive is Integer range 1 .. Integer'Last;

Ces deux sous-types d’Integer s’utilisent lorsqu’un objet entier doit contenir une valeur positive ou nulle (Natural) ou strictement positive (Positive). 6.1.4 Attributs applicables aux sous-types

De manière générale, les attributs applicables à un type sont utilisables avec tout sous-type de ce type (exemple 6.5). Il faut simplement préciser que, si la valeur retournée par un attribut appliqué à un sous-type appartient au type de base, elle n’est pas soumise à la contrainte imposée par le sous-type.

Exemple 6.5 Attributs et sous-types (voir exemple 6.2).

T_Jours_Travail'Firstattribut de valeur Lundi;

T_Jours_Travail'Succ(Vendredi)attribut de valeur Samedi;

T_Jours_Travail'Pred(Jour)erreur générée à l’exécution si Jour vaut Lundi;

T_Jours_Travail'Val(0)attribut de valeur Lundi;

T_Jours_Travail'Val(6)attribut de valeur Dimanche;

T_Chiffre'Pos(0)attribut de valeur 0; T_Negatifs'Lastattribut de valeur –1;

T_Negatifs'Succ(T_Negatifs'Last)attribut de valeur 0.

Finalement, comme le nom d’un sous-type discret représente également l’in- tervalle des valeurs du sous-type, ce nom peut s’utiliser partout où un intervalle est autorisé (sauf dans une contrainte d’intervalle), en particulier dans les instructions

for (sect. 3.5) et case (sect. 5.3) comme par exemple: -- La boucle s'effectuera cinq fois

SOUS-TYPES 133

for Jour in T_Jours_Travail loop

...;

end loop;

case Jour is -- Jour du type

T_Jours_De_La_Semaine

when T_Jours_Travail => ...; -- Travailler

when Samedi | Dimanche => ...; -- Se reposer

end case;

6.1.5 Tests d’appartenance

Il existe deux tests d’appartenance (ressemblant à deux opérateurs) in et not in, de priorité égale à celle des opérateurs de comparaison. Ils permettent de

vérifier si une valeur appartient à un intervalle, bornes comprises (exemple 6.6). Le type de l’intervalle (ou du sous-type) doit être un type discret [ARM 3.2] alors que le résultat est naturellement de type Boolean. Comme in et not in ne sont pas

des opérateurs, ils ne peuvent donc pas être surchargés (sect. 4.9). Exemple 6.6 Utilisation de tests d’appartenance.

Jour in T_Jours_Travailvrai si Jour est un jour de travail;

Jour not in T_Jours_Travailvrai si Jour est Samedi ou Dimanche;

Nombre in T_Chiffrevrai si Nombre est un chiffre;

Lettre in 'A'..'Z'vrai si Lettre est une majuscule;

TYPES NUMÉRIQUES 134

6.2 TYPES NUMÉRIQUES