32 votes

Pourquoi les anciennes spécifications du langage C exigent-elles que les variables fonction-locales soient déclarées à l’avance?

Dans le langage de programmation C, le langage des révisions, j'ai travaillé avec des appliqués avant les déclarations de variables avant tout non-déclarative/assignative expressions susceptibles d'être évalués. C++ semble avoir renoncé à cette exigence de toutes les versions. Je reconnais aussi une version plus moderne de C ont renoncé à cette exigence, mais je n'ai pas encore utiliser l'une de ces normes.

La question que je me pose est: est-ce Qu'raisons historiques, était là pour empêcher le langage C de déclarer librement à la demande au lieu de l'avant?

Évidemment, il ya un certain nombre de raisons qui viennent à l'esprit à partir d'un point de vue de l'ingénierie, mais aucun d'entre eux semblent tout à fait plausibles pour moi.

  1. La prévention d'un obscur compilateur de comportement erreur se produise (comme infini analyse de boucles, d'une massive de la mémoire de la météorisation pour l'évaluation, ou quelque étrange cas du coin avec les Macros.)
  2. La prévention indésirables sortie du compilateur. Cela pourrait être quelque chose de symbole de sortie embrouiller le processus de débogage et la facilité de développement d'outils de débogage, inattendus de la pile de stockage de commandes.
  3. La lisibilité. Je trouve cela difficile à avaler, et, voyant que le C, le tout conçu pour des raisons de lisibilité par rapport à d'autres langues de l'époque, n'a pas d'appliquer ce type de structure près n'importe où ailleurs. (Sauf si vous voyez le prototypage comme étant un analogue de l'application, mais si je me souviens prototypes ont été ajoutés dans le '89 spec.)
  4. Complexité de mise en œuvre et des raisons pratiques. C'est celle que je suis plus enclin à croire. Comme les ingénieurs, nous avons à faire certaines considérations afin de livrer un produit viable dans un laps de temps imparti. Alors que je le ferai que le paysage professionnel de l'Informatique et de Génie Logiciel ont tous les deux changé de façon spectaculaire, l'Entreprise est toujours en activité. À la fin de la journée, je suis sûr que Bell voulait un produit fini qui peut être utilisé dans l'environnement Unix mettre en valeur ce qu'ils avaient accompli.

Quelqu'un a une bonne sources de la sauvegarde de tout ce qui précède? Ai-je raté quelque chose d'entièrement? Nous pouvons spéculer de l'aube à la tombée de la nuit, mais je suis à la recherche pour de bon dur de références.

19voto

ecatmur Points 64173

En regardant le début de l' (6e édition Unix, 1975) C manuel de Dennis Ritchie, page d'accueil, dans cette version de la fonction de variables locales pourraient seulement être déclarées au début d'une fonction:

La fonction-déclaration est juste une instruction composée, qui peut avoir de déclarations au début.

fonction-instruction: { déclaration-listeopt de l'instruction de la liste }

déclaration-la liste n'est pas définie (omission), mais peut être facilement supposé avoir de grammaire:

déclaration de la liste: déclaration déclaration-listeopt.

Aucune autre instruction composée est autorisé à contenir de variable (voire aucune) déclarations.

De toute évidence, cela simplifie la mise en œuvre; dans les premiers compilateur de code source c02.c - tête de la fonction la fonction blkhed() seulement des besoins de la somme de l'espace de pile utilisé par auto des déclarations de variables, dans le même temps, l'enregistrement de leur pile de décalage, et émettent un code pour augmenter le pointeur de pile par le montant approprié. Sur la sortie de la fonction (en return ou de tomber de la fin) de la mise en œuvre a juste besoin de restaurer les sauvés pointeur de pile.

Le fait que le K&R l'estime nécessaire d'indiquer que "les déclarations de variables (y compris les initialisations) peut suivre l'accolade gauche qui introduit une instruction composée, et pas seulement celui qui commence une fonction" est une allusion au fait que, à ce point, c'est un relativement récente fonctionnalité. Il indique également que les combinés de la déclaration de syntaxe d'initialisation a été aussi une fonction récente, et en effet en 1975 dans le manuel declarators ne peut pas avoir les initialiseurs.

En 1975, manuel de l'article 11.1, déclare expressément que:

C est pas un bloc structuré de la langue; ce peut être à juste titre considérée comme un défaut.

Bloc-déclaration et initialisation déclarations (K&R) de l'adresse de ce vice, et mixtes déclarations et le code (C99) sont la suite logique.

10voto

Andreas Grapentin Points 1968

En C89, les définitions de variables sont nécessaires pour être au début d'un bloc. (Voir le C standard pour la définition d'un bloc), C'est pour autant que je sais faire pour simplifier la façon dont les variables sont traitées en assembleur. Par exemple, laissez-nous jeter un oeil à une simple fonction:

void foo()
{
    int i = 5;
    printf("%i\n", i);
}

lorsque le ccg se traduit par cette fonction dans le code assembleur, l'appel à foo() permettrait de réduire à un tas d'instructions, y compris la mise en place d'une structure de pile pour la portée de la fonction. cette structure de pile inclut l'espace pour les variables définies dans le champ d'application de la fonction, et pour correspondre à la même portée dans le langage de plus haut niveau C, ils doivent être définies au début du bloc.

À la fin, c'était à propos de la facilité de mise en œuvre, et aussi de l'efficacité, parce que la déclaration d'un tas de variables à la fois, qui, au début d'un bloc, permet au compilateur de vrac-push sur la pile, et autour de ~89, qui a été aussi un facteur de performance.

Bien sûr, cette réponse est très simplifié et ne vise qu'à donner une brève idée sur les raisons de ce qui a été fait de la façon dont c'était fait. Pour plus d'Informations, vous devriez probablement lire certains projets du début du C89 standard.

10voto

AndreyT Points 139512

Une réponse courte, ce n'est pas vraiment une réponse plus: langage C d'abord hérité de cette déclaration de l'ordre de restriction de son prédécesseur: B de langue. Pourquoi cela a été fait de cette façon en langue B I, malheureusement, ne sais pas.

Notez également que dans la naissante C (décrit dans "C Manuel de Référence"), il était illégal pour initialiser des variables (même locaux) avec des expressions constantes.

int a 5;
int b a; /* ERROR in nascent versions of C */

(une note de côté: dans CRM syntaxe d'initialisation n'a pas inclus l' = de caractères). Dans le cas général, cette niées le principal avantage de code déclarations de variables: la possibilité de spécifier un sens au moment de l'exécution de la valeur comme un initialiseur. Même en beaucoup plus moderne C89/90 cette restriction encore officiellement demandé à agréger les initialiseurs (bien que la plupart des compilateurs ignoré)

int a = 5, b = a;
struct { int x, y; } s = { a, b }; /* ERRROR even in C89/90 */ 

Seulement en C99, il est devenu possible d'utiliser des valeurs d'exécution pour tous les types de locaux de l'initialisation. Ce enfin débloqué la pleine puissance de code de déclarations de variables, de sorte qu'il est parfaitement logique que le C99 a été le seul à présenter.

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