27 votes

Pourquoi un compilateur C / C ++ doit-il connaître la taille d'un tableau au moment de la compilation?

Je sais que les normes C précédant C99 (ainsi que C ++) indiquent que la taille d'un tableau sur la pile doit être connue au moment de la compilation. Mais pourquoi ça? Le tableau sur la pile est alloué au moment de l'exécution. Alors, pourquoi la taille est-elle importante lors de la compilation? J'espère que quelqu'un m'expliquera ce qu'un compilateur fera avec la taille au moment de la compilation. Merci.

L'exemple d'un tel tableau est:

 void func()
{
    /*Here "array" is a local variable on stack, its space is allocated
     *at run-time. Why does the compiler need know its size at compile-time?
     */
   int array[10]; 
}
 

57voto

caf Points 114951

Pour comprendre pourquoi la variable de la taille des tableaux sont plus compliquées à mettre en œuvre, vous avez besoin de savoir un peu comment automatique de la durée de stockage ("local") variables sont généralement mises en œuvre.

Les variables locales ont tendance à être stockées sur l'exécution de la pile. La pile est en fait un large éventail de la mémoire, qui est séquentiel attribué aux variables locales et de l'index pointant vers le présent "high water mark". Cet indice est le pointeur de pile.

Lorsqu'une fonction est entré, le pointeur de pile est déplacé dans une direction pour allouer de la mémoire sur la pile pour les variables locales; lorsque la fonction se termine, le pointeur de pile est déplacé dans l'autre sens, à libérer les.

Cela signifie que l'emplacement réel de variables locales dans la mémoire est définie uniquement par référence à la valeur du pointeur de pile à l'entrée de la fonction1. Le code dans une fonction, on doit accéder à des variables locales par le biais d'un décalage à partir du pointeur de pile. L'exacte des compensations à être utilisés dépendent de la taille des variables locales.

Maintenant, lorsque toutes les variables locales ont une taille fixe au moment de la compilation, ces décalages du pointeur de pile sont également fixe, de sorte qu'ils peuvent être codées directement dans les instructions que le compilateur émet. Par exemple, dans cette fonction:

void foo(void)
{
    int a;
    char b[10];
    int c;

a peut être accessible en tant que STACK_POINTER + 0, b peut être accessible en tant que STACK_POINTER + 4, et c peut être accessible en tant que STACK_POINTER + 14.

Cependant, lors de l'introduction d'une variable tableau de taille, ces décalages peuvent plus être calculée au moment de la compilation; certains d'entre eux vont varier en fonction de la taille de la matrice a sur cette invocation de la fonction. Cela rend les choses beaucoup plus compliquées pour les rédacteurs du compilateur, car il faut maintenant écrire le code qui accède STACK_POINTER + N - et depuis N varie lui-même, il doit également être stocké quelque part. Souvent, cela signifie faire deux accès - l'un à l' STACK_POINTER + <constant> à la charge N, puis une autre pour la charge ou le magasin le locale réelle de la variable d'intérêt.


1. En fait, "la valeur du pointeur de pile à l'entrée de la fonction" est une valeur d'utilité d'avoir autour, qu'il a un nom qui lui est propre - le pointeur de l'image - et de nombreux Processeurs de fournir un registre distinct dédié à stocker le pointeur de cadre. Dans la pratique, il est généralement le pointeur de l'image à partir de laquelle l'emplacement des variables locales est calculé, plutôt que le pointeur de pile elle-même.

5voto

Denis Hennessy Points 3085

Le compilateur doit générer le code pour créer l'espace pour le cadre sur la pile pour contenir le tableau et d'autres variables locales locales. Pour cela, il a besoin de la taille du tableau.

5voto

kotlinski Points 12815

Il n'est pas quelque chose d'extrêmement compliqué de soutien, donc, la raison C89 n'autorise pas c'est pas parce que c'était impossible alors.

Il y a toutefois deux raisons importantes pour lesquelles il n'est pas en C89:

  1. Le moteur d'exécution de code seront moins efficace si la taille du tableau n'est pas connue au moment de la compilation.
  2. Le soutien de ce qui rend la vie plus difficile pour les rédacteurs du compilateur.

Historiquement, il a été très important que les compilateurs C devrait être (relativement) facile à écrire. Aussi, il devrait être possible de faire des compilateurs simple et assez petit pour s'exécuter sur le modeste de systèmes informatiques (par 80s normes). Une autre caractéristique importante, C est que le code généré doit constamment être extrêmement efficace, sans surprise,

Je pense qu'il est regrettable que ces valeurs ne sont plus valables pour le C99.

3voto

Marvo Points 5444

Dépend de la façon dont vous allouer le tableau.

Si vous créer une variable locale, et de spécifier une longueur, alors c'est important parce que le compilateur a besoin de savoir combien d'espace à allouer sur la pile pour les éléments de la matrice. Si vous ne spécifiez pas de la taille de la matrice, il ne sait pas de combien d'espace à réserver pour les éléments du tableau.

Si vous créez simplement un pointeur vers un tableau, puis tout ce que vous devez faire est d'allouer l'espace pour le pointeur lui-même, et puis vous pouvez créer dynamiquement des éléments d'un tableau au moment de l'exécution. Mais dans cette forme de la création de la matrice, vous êtes à l'allocation d'espace pour les éléments du tableau dans le tas, pas sur la pile.

3voto

seand Points 3426

Disons que vous créez un tableau de taille variable sur la pile. La taille du cadre de pile nécessaire à la fonction ne sera pas connue au moment de la compilation. Ainsi, C a supposé que certains environnements d'exécution nécessitent que cela soit connu à l'avance. D'où la limitation. C remonte au début des années 1970. Beaucoup de langues à l'époque avaient une apparence "statique" (comme Fortran)

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