Question

Le Article Wikipédia sur ANSI C dit:

L'un des objectifs du processus de normalisation ANSI C était de produire un sur-ensemble de K&R C (la première norme publiée), incorporant de nombreuses fonctionnalités non officielles introduites par la suite.Cependant, le comité des normes a également inclus plusieurs nouvelles fonctionnalités, telles que des prototypes de fonctions (empruntés au langage de programmation C++) et un préprocesseur plus performant.La syntaxe des déclarations de paramètres a également été modifiée pour refléter le style C++.

Cela me fait penser qu'il y a des différences.Cependant, je n'ai pas vu de comparaison entre K&R C et ANSI C.Existe-t-il un tel document ?Si non, quelles sont les principales différences ?

MODIFIER:Je crois que le livre K&R dit "ANSI C" sur la couverture.Du moins, je crois que la version que j'ai chez moi le fait.Alors peut-être qu'il n'y a plus de différence ?

Était-ce utile?

La solution

Il peut y avoir une certaine confusion ici sur ce qu'est « K&R C ».Le terme fait référence à la langue comme documentée dans la première édition de "The C Programming Language". Grosso modo:le langage d'entrée du compilateur C des Bell Labs vers 1978.

Kernighan et Ritchie ont participé au processus de normalisation ANSI.Le dialecte « ANSI C » a remplacé « K&R C » et les éditions ultérieures de « The C Programming Language » adoptent les conventions ANSI."K&R C" est un "langage mort", sauf dans la mesure où certains compilateurs acceptent encore le code existant.

Autres conseils

Les prototypes de fonctions constituaient le changement le plus évident entre le K&R C et le C89, mais il y en avait bien d'autres.De nombreux travaux importants ont également été consacrés à la standardisation de la bibliothèque C.Même si la bibliothèque C standard était une codification des pratiques existantes, elle codifiait plusieurs pratiques existantes, ce qui rendait la tâche plus difficile.P J.Le livre de Plauger, La bibliothèque standard C, est une excellente référence et raconte également certains détails des coulisses de pourquoi la bibliothèque s'est retrouvée ainsi.

La norme ANSI/ISO C est très similaire à K&R C à bien des égards.Il était prévu que la plupart du code C existant s'appuie sur des compilateurs ANSI sans trop de changements.Mais surtout, à l’époque pré-standard, la sémantique du langage était ouverte à l’interprétation de chaque fournisseur de compilateur.ANSI C a introduit une description commune de la sémantique du langage qui met tous les compilateurs sur un pied d'égalité.Il est facile de tenir cela pour acquis aujourd'hui, une vingtaine d'années plus tard, mais il s'agit d'une réalisation importante.

Pour la plupart, si vous n'avez pas de base de code C pré-standard à maintenir, vous devriez être heureux de ne pas avoir à vous en soucier.Si c’est le cas – ou pire encore, si vous essayez de mettre un ancien programme aux normes plus modernes – alors vous avez mes sympathies.

Il existe quelques différences mineures, mais je pense que les éditions ultérieures de K&R sont pour ANSI C, il n'y a donc plus de réelle différence.
"C Classic", faute de meilleurs termes, avait une manière légèrement différente de définir les fonctions, c'est-à-dire

int f( p, q, r )  
int p, float q, double r;  
{  
    // Code goes here  
}

Je crois que l'autre différence réside dans les prototypes de fonctions.Les prototypes n'étaient pas obligés - en fait, ils ne le pouvaient pas - de prendre une liste d'arguments ou de types.En ANSI C, ils le font.

  1. prototype de fonction.
  2. qualificatifs constants et volatils.
  3. large prise en charge des personnages et internationalisation.
  4. permettre l'utilisation du pointeur de fonction sans déréférencement.

Une autre différence est qu’il n’est pas nécessaire de définir les types de retour de fonction et les types de paramètres.Ils seraient supposés être des entiers.

f(x)
{
    return x + 1;
}

et

int f(x)
int x;
{
    return x + 1;
}

sont identiques.

  • PROTOTYPAGE DE FONCTION : ANSI C adopte la technique de prototype de fonction C++ où la définition et la déclaration de fonction incluent les noms de fonction, les arguments, les types de données et les types de données de valeur de retour. Le prototype de fonction permet aux compilateurs ANSI de vérifier l'appel de fonction dans le programme utilisateur qui transmet un numéro d'argument non valide. ou des types de données d'arguments incompatibles. Ceux-ci corrigent une faiblesse majeure des compilateurs K&R C : un appel invalide dans le programme utilisateur réussit souvent la compilation mais provoque le crash du programme lors de son exécution.

La différence est :

  1. Prototype
  2. large prise en charge des caractères et internationalisation
  3. Prise en charge des mots-clés const et volatiles
  4. permettre aux pointeurs de fonction d'être utilisés comme déréférencement

Les principales différences entre ANSI C et K&R C sont les suivantes :

  • prototypage de fonctions
  • prise en charge des qualificatifs de type de données const et volatile
  • prend en charge les caractères larges et l'internationalisation
  • permettre l'utilisation de pointeurs de fonction sans déréférencement

ANSI C adopte la technique de prototype de fonction C++ où la définition et la déclaration de fonction incluent les noms de fonction, les types de données des arguments et les types de données de valeur de retour.Le prototype de fonction permet au compilateur ANSI C de vérifier les appels de fonction dans les programmes utilisateur qui transmettent des nombres d'arguments non valides ou des types de données d'arguments incompatibles.Ceux-ci corrigent une faiblesse majeure du compilateur K&R C.

Exemple:to déclare une fonction foo et exige que foo prenne deux arguments

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }

La plus grande différence, je pense, réside dans le prototypage des fonctions et la syntaxe permettant de décrire les types d’arguments de fonction.

Une différence majeure que personne n'a encore mentionnée est qu'avant l'ANSI, le C était défini en grande partie par un précédent plutôt que par une spécification ;dans les cas où certaines opérations auraient des conséquences prévisibles sur certaines plateformes mais pas sur d'autres (par ex.utilisant des opérateurs relationnels sur deux pointeurs non liés), le précédent favorisait fortement la mise à disposition des garanties de la plate-forme pour le programmeur.Par exemple:

  1. Sur les plates-formes qui définissent un classement naturel parmi tous les pointeurs vers tous les objets, on peut compter sur l'application des opérateurs relationnels à des pointeurs arbitraires pour obtenir ce classement.

  2. Sur les plates-formes où le moyen naturel de tester si un pointeur est "supérieur" à un autre n'a jamais d'effet secondaire autre que celui de donner une valeur vraie ou fausse, l'application des opérateurs relationnels à des pointeurs arbitraires pourrait également être considérée comme n'ayant jamais d'effet secondaire. -effets autres que donner une valeur vraie ou fausse.

  3. Sur les plates-formes où deux ou plusieurs types entiers partageaient la même taille et la même représentation, un pointeur vers un tel type entier pouvait être utilisé pour lire ou écrire des informations de tout autre type avec la même représentation.

  4. Sur les plates-formes en complément à deux où les débordements d'entiers s'enroulent naturellement silencieusement, une opération impliquant des valeurs non signées inférieures à "int" pourrait être considérée comme se comportant comme si la valeur n'était pas signée dans les cas où le résultat serait compris entre INT_MAX+1u et UINT_MAX et il n'a pas été promu à un type plus grand, ni utilisé comme opérande gauche de >>, ni aucun des opérandes de /, %, ou tout autre opérateur de comparaison. À propos, la justification de la norme donne cela comme l'une des raisons pour lesquelles les petits types non signés sont promus au format signé..

Avant C89, il n'était pas clair jusqu'où les compilateurs pour les plates-formes où les hypothèses ci-dessus ne seraient pas naturellement valables pourraient être censés aller de toute façon pour maintenir ces hypothèses, mais il ne faisait aucun doute que les compilateurs pour les plates-formes qui pourraient facilement et à moindre coût maintenir de telles hypothèses devrait le faire.Les auteurs de la norme C89 n’ont pas pris la peine de le dire expressément parce que :

  1. Les compilateurs dont les auteurs n'étaient pas délibérément obtus continueraient à faire de telles choses lorsque cela était possible sans qu'on le leur dise (la justification avancée pour promouvoir de petites valeurs non signées en valeurs signées renforce fortement ce point de vue).

  2. La norme exigeait seulement que les implémentations soient capables d'exécuter un programme éventuellement artificiel sans débordement de pile, et reconnaissait que même si une implémentation obtuse pouvait traiter n'importe quel autre programme comme invoquant un comportement non défini, elle ne pensait pas que cela valait la peine de s'inquiéter de l'écriture obtuse des rédacteurs de compilateurs. des implémentations « conformes » mais inutiles.

Bien que "C89" ait été interprété à l'époque comme signifiant "le langage défini par C89, ainsi que toutes les fonctionnalités et garanties supplémentaires fournies par la plate-forme", les auteurs de gcc ont poussé une interprétation qui exclut toutes les fonctionnalités et garanties au-delà de celles exigées par C89.

Malgré toutes les prétentions du contraire, K&R était et est tout à fait capable de fournir n'importe quelle sorte de choses, du bas vers le matériel.Le problème est maintenant de trouver un compilateur (de préférence gratuit) capable de fournir une compilation propre sur quelques millions de lignes de K&R C sans avoir à s'en occuper. Et fonctionnant sur quelque chose comme un processeur multicœur AMD.

Pour autant que je sache, après avoir examiné la source de la série GCC 4.x.x, il n'existe pas de hack simple pour réactiver les fonctionnalités de décalage -traditional et -cpp-traditional vers leur état de fonctionnement précédent sans plus d'efforts que ce à quoi je suis prêt à le faire. mettre dedans.Et plus simple de créer un compilateur pré-ansi K&R à partir de zéro.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top