Next: La compilation séparée
Up: Les déclarations
Previous: Durée de vie
Sous-sections
Lors de l'exécution d'un programme C il y a trois zones de mémoire
différentes, correspondant aux trois durées de vies possibles :
- -
- la zone contenant les variables statiques ;
- -
- la zone contenant les variables automatiques
(cette zone est gérée en pile puisqu'en C, toute fonction peut être
récursive) ;
- -
- la zone contenant les variables dynamiques
(cette zone est généralement appelée le tas).
Un tel découpage se rencontre couramment dans les langages de programmation.
Généralement cependant, il n'est pas nécessaire au programmeur de
déclarer la classe dans laquelle il désire mettre une variable, cette
classe étant choisie de manière autoritaire par le langage.
Les concepteurs du langage C ont voulu offrir plus de souplesse aux
programmeurs.
En effet, nous venons de voir que l'on pouvait mettre dans la classe des
variables statiques une variable qui était locale à une
instruction composée.
D'autre part, pour des raisons d'efficacité des programmes générés,
les concepteurs du langage ont créé une nouvelle classe : la classe
register.
Quand le programmeur déclare par exemple :
register int i;
ceci est une indication au compilateur, lui permettant d'allouer la variable
dans une ressource de la machine dont l'accès sera plus rapide que l'accès
à une mémoire (si une telle ressource existe).
Il existe 5 mots-clés du langage que la grammaire nomme
spécificateur
de classe de mémoire.
Il s'agit des mots-clés suivants :
- auto
- Ce spécificateur de classe mémoire n'est autorisé que pour les
variables locales à une instruction composée.
Il indique que la variable concernée à une durée de vie locale à
l'instruction composée.
Si la déclaration d'une variable locale ne comporte pas de spécificateurs de
classe de mémoire, c'est auto qui est pris par défaut.
Exemple :
{
auto int i;
...
}
- static
- Ce spécificateur de classe mémoire est autorisé pour les
déclarations de variables et de fonctions.
Pour les déclarations de variables, il indique que la variable concernée
a une durée de vie globale.
Dans tous les cas, (variables et fonctions), il indique que le nom
concerné ne doit pas être exporté par l'éditeur de liens.
Exemple :
static int i; /* i ne sera pas exporté par l'éditeur de liens */
int j; /* j sera exporté par l'éditeur de liens */
static void f() /* f ne sera pas exporté par l'éditeur de liens */
{
static int k; /* k aura une durée de vie globale */
...
}
void g() /* g sera exportée par l'éditeur de liens */
{
...
}
- register
- Ce spécificateur n'est autorisé que pour les déclarations
de variables locales à une instruction composée, et pour les déclarations
de paramètres de fonctions.
Sa signification est celle de auto avec en plus une indication pour le
compilateur d'allouer pour la variable une ressource à accès rapide.
Le programmeur est supposé mettre une variable dans la classe register
quand elle est fortement utilisée par l'algorithme.
Il y a cependant une contrainte : une telle variable n'a pas d'adresse,
impossible donc de lui appliquer l'opérateur
&
.
- extern
- Ce spécificateur est autorisé pour les déclarations de
variables et de fonctions.
Il sert a indiquer que l'objet concerné a une durée de vie globale et
que son nom est connu de l'éditeur de liens.
- typedef
- Ce spécificateur n'a rien à voir avec les classes de mémoire :
il sert à définir des types.
Son utilité sera vue plus loin.
On peut faire les critiques suivantes :
- 1.
- auto ne peut servir que pour les variables locales, mais si
on ne le met pas, il est pris par défaut. Conclusion : il ne sert à rien.
- 2.
- static sert à deux choses très différentes : il permet de
rendre statique une variable locale, et c'est une utilisation légitime,
mais il sert aussi à cacher à l'éditeur de liens les variables globales.
On rappelle que par défaut (c'est à dire sans le mot-clé static,)
les variables globales sont connues de l'éditeur de liens.
Il aurait mieux valu faire l'inverse : que par défaut les
variables globales soient cachées à l'éditeur de liens, et avoir un
mot-clé (par exemple export), pour les lui faire connaître.
- 3.
- register a été introduit dans le langage pour optimiser les
programmes.
Avec les techniques modernes de compilation, il ne sert à rien car le
compilateur est mieux à même que le programmeur d'allouer les registres
de la machine de manière efficace.
Ne pas oublier en outre, qu'il y a une contrainte attachée à l'utilisation
de variables register : l'impossibilité de leur appliquer l'opérateur
&
.
- 4.
- extern et typedef n'ont rien à voir avec les classes
de mémoire : ils ne sont là que pour des raisons syntaxiques.
Next: La compilation séparée
Up: Les déclarations
Previous: Durée de vie
Bernard Cassagne
1998-12-09