Developpez.com - C
X

Choisissez d'abord la catégorieensuite la rubrique :

next up previous contents index
Next: La compilation séparée Up: Les déclarations Previous: Durée de vie

Sous-sections

Classes de mémoire

 

Position du problème

  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).

Les spécificateurs de classe de mémoire

            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.

Discussion

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 up previous contents index
Next: La compilation séparée Up: Les déclarations Previous: Durée de vie
Bernard Cassagne
1998-12-09
Contacter le responsable de la rubrique C