49 votes

Qu'y avait-il avec la soupe typedef historique pour les entiers dans les programmes C?

C'est un peut stupide question dont la réponse je devrais savoir.

Il y a quinze ans, beaucoup de code C je regarderais a eu des tonnes de entier typedefs dans une plate-forme spécifique #ifdefs. Il semblait que chaque programme ou d'une bibliothèque, j'ai regardé avaient leur propre, mutuellement incompatibles typedef soupe. Je n'en savons pas beaucoup sur la programmation à l'époque et il nous semblait bizarre tas de sauter à travers des cerceaux juste pour dire au compilateur quel genre de entier vous vouliez l'utiliser.

J'ai mis en place une histoire dans mon esprit pour expliquer ce que sont ces typedefs étaient sur, mais je ne sais pas vraiment si c'est vrai. Ma conjecture est essentiellement que lorsque C a d'abord été développé et standardisé, il n'était pas réalisé combien il était important d'être en mesure de plate-forme, indépendamment, un entier de type d'une certaine taille, et donc l'original de tous les C les types d'entiers peuvent être de tailles différentes sur différentes plates-formes. Ainsi, tout le monde essaie d'écrire des C portable code a faire eux-mêmes.

Est-ce correct? Si oui, comment étaient les programmeurs à utiliser les C les types d'entiers? Je veux dire, dans un langage de bas niveau avec beaucoup de bits tourner, n'est-il pas important d'être capable de dire "ceci est un entier de 32 bits"? Et puisque la langue a été normalisé en 1989, il n'y avait certains l'ont pensé que les gens seraient en essayant d'écrire du code portable?

66voto

John Hascall Points 70

Quand ca a commencé ordinateurs étaient moins homogène et beaucoup moins qu'aujourd'hui. Il était considéré comme plus important pour la portabilité du int types de la taille naturelle(s) de l'ordinateur. Demander un entier de 32 bits sur 36 bits, le système est probablement le résultat de mauvais code.

Et puis vint omniprésente de réseautage où vous travaillez avec la taille de fil champs. Maintenant interopérabilité semble bien différent. Et le "octet" devient, de facto, le quanta de types de données.

Maintenant, vous devez ints exacte des multiples de 8-bits, vous pouvez maintenant obtenir typedef soupe et puis finalement le standard rattrape et nous avons des noms standard pour eux et la soupe n'est pas nécessaire.

18voto

chux Points 13185

C est un premier succès a été dû à la flexibilité de s'adapter à presque toutes les variantes des architectures @John Hascall avec:
1) natif entier tailles de 8, 16, 18, 24, 32, 36, etc. bits,
2) variante entier signé modèles: complément de 2, 1 de complément, entier signé et
3) divers endian, grand, petit et d'autres.

Comme le codage développé, d'algorithmes et d'échange de données a poussé, une plus grande uniformité et donc la nécessité pour les types qui met 1 et 2 ci-dessus sur l'ensemble des plateformes. Les codeurs de rouler leur propre comme typedef int int32 à l'intérieur d'un #if .... Les nombreuses variantes de qui a créé la soupe, comme indiqué par l'OP.


C99 introduite (u)int_leastN_t, (u)int_fastN_t, (u)intmax_t pour le rendre portable encore un peu de minimum de largeur de bit-ness types. Ces types sont nécessaires pour N = 8,16,32,64.

Également introduites sont semi-optionnel (voir ci-dessous **) comme (u)intN_t qui a les attributs supplémentaires qu'ils doivent être complément de 2 et pas de rembourrage. Il est de ces types populaires qui sont donc largement souhaitée et utilisé pour éclaircir la entier de la soupe.


comment étaient les programmeurs à utiliser les C les types d'entiers?

Par l'écriture souple code qui n'a pas dépendent fortement de peu de largeur. Est est assez facile à coder strtol() en utilisant uniquement LONG_MIN, LONG_MAX , sans égard à la largeur de bits/endian/integer encodage.

Pourtant, de nombreuses tâches de codage obliger de largeur précise les types et complément de 2 pour faciliter le haut rendement de codage. Il est préférable, dans ce cas, de renoncer à la portabilité de 36 bits pour les machines et les 32 bits de signe des grandeurs et le bâton avec 2N large (complément de 2 pour la signature des entiers. Divers CRC et d'algorithmes de chiffrement et de formats de fichiers viennent à l'esprit. Donc la nécessité d'une largeur fixe de types et un certain (C99).


Aujourd'hui, il y a encore des problèmes qui doivent encore être géré. Exemple: Les promotions habituelles int/unsigned perdre un peu de contrôle que ces types de peut être de 16, 32 ou 64.


**

Ces types sont en option. Toutefois, si une mise en œuvre fournit les types d'entiers avec des largeurs de 8, 16, 32, ou 64 bits, pas de rembourrage bits, et (pour les types signés) qui ont une représentation en complément à deux, il doit définir les correspondants typedef noms. C11 7.20.1.1 Exacte de la largeur des types d'entiers 3

11voto

Yimin Rong Points 568

Je me souviens de cette période, et je suis coupable de faire de même!

Une question était la taille de l' int, il pourrait être le même que shortou long ou entre les deux. Par exemple, si vous travaillez avec les formats de fichiers binaires, il est impératif que tout aligner. Octet de commande compliqué les choses ainsi. Beaucoup de développeurs sont allés le paresseux route et viens fwrite de ce que, au lieu de choisir les numéros à part, octet par octet. Lorsque les machines mises à niveau pour de plus longues longueurs de mots, tout l'enfer s'est déchaîné. Donc, typedef a été facile hack pour résoudre ce problème.

Si la performance est un problème, comme il a été souvent à l'époque, int est garanti pour être la machine la plus rapide de taille naturelle, mais si vous avez besoin d'32 bits, et int a été plus courte que cela, vous étiez en danger de retournement.

Dans le langage C, sizeof() n'est pas censé être résolu au préprocesseur scène, ce qui rendait les choses compliquées parce que tu ne pouvais pas faire #if sizeof(int) == 4 par exemple.

Personnellement, certains de la justification était aussi travailler à partir d'un langage assembleur état d'esprit et de ne pas être disposés à l'abstraction de la notion de ce qu' short, int et long sont pour. À l'époque, l'assembleur a été utilisé en C assez fréquemment.

De nos jours, il y a beaucoup de non-formats de fichier binaires, JSON, XML, etc. où il n'a pas d'importance ce que la représentation binaire est. Ainsi, de nombreuses plates-formes populaires se sont installés sur un 32 bits int ou plus, ce qui est généralement suffisant pour la plupart des fins, donc il y a moins d'un problème de roulement.

6voto

John Bode Points 33046

C est un produit du début des années 1970, lorsque le calcul de l'écosystème a été très différente. Au lieu de millions d'ordinateurs à parler les uns aux autres sur un réseau étendu, vous aviez peut-être une centaine de milliers de systèmes dans le monde entier, chacun exécutant un peu monolithique apps, avec presque pas de communication entre les systèmes. Vous ne pouvais pas supposer que tous les deux architectures avait le même mot tailles, ou représenter des nombres entiers signés de la même manière. Le marché était encore assez petit pour qu'il n'y avait pas perçu le besoin de normaliser, les ordinateurs n'ont pas de parler les uns aux autres (beaucoup), et personne, bien que beaucoup au sujet de la portabilité.

Si oui, quelles sont les programmeurs à utiliser les C les types d'entiers?

Si vous souhaitez écrire au maximum du code portable, puis vous n'avez pas supposer quoi que ce soit au-delà de ce que la Norme de la garantie. Dans le cas d' int, cela signifie que vous n'avez pas supposer qu'il pourrait représenter quoi que ce soit en dehors de la plage [-32767,32767], ni avez-vous supposer qu'il serait représenté en complément de 2, ni avez-vous supposer que c'était une largeur spécifique, il pourrait être plus large que 16 bits, mais ne représentent encore qu'un 16 bits de large, s'il contenait une padding bits).

Si vous n'avez pas de soins sur la portabilité, ou vous ont fait des choses qui étaient de nature non portable (qui peu tourner est souvent le cas), alors vous avez utilisé quel que soit le type(s) rencontré à vos exigences.

Je n'ai élevé pour la plupart des applications au niveau de la programmation, j'ai donc été moins inquiet au sujet de la représentation que j'étais sur la plage. Même si, j'ai parfois besoin de plonger vers le bas dans des représentations binaires, et il y a toujours peu de moi dans le cul. Je me souviens d'écrire du code dans le début des années 90 qui avait à exécuter sur le classique de MacOS, Windows 3.1, et Solaris. J'ai créé un tas de dénombrement des constantes pour les 32 bits de masques, qui a bien fonctionné sur le Mac et Unix boîtes, mais n'ont pas pu compiler sur la zone de Windows parce que sous Windows, un int seulement de 16 bits de large.

2voto

supercat Points 25534

C a été conçu comme un langage qui pourrait être porté à la plus large gamme de machines que possible, plutôt que comme un langage qui permettrait à la plupart des types de programmes à exécuter sans modification sur une telle gamme de machines. Pour la plupart des cas, C est types:

  • 8 bits type si l'on est disponible, ou bien le plus petit type qui est au moins 8 bits.

  • Un type 16 bits, si disponible, sinon le plus petit type qui est au moins 16 bits.

  • Une version 32 bits de type, s'il est disponible, ou bien un type qui est au moins 32 bits.

  • Un type qui sera de 32 bits si les systèmes peuvent gérer de telles choses de manière aussi efficace que de 16 bits ou 16 bits autrement.

Si le code nécessaire de 8, 16 ou 32 bits types et serait peu susceptible d'être utilisable sur des machines qui ne les soutient pas, il n'y avait pas de problème particulier avec ce type de code concernant l' char, short, et long 8, 16 et 32 bits, respectivement. Les seuls systèmes qui n'ont pas la carte les noms de ces types de ceux qui ne pouvaient pas soutenir ces types et ne serait pas utile poignée de code qui en ont besoin. Ces systèmes pourraient être limités à l'écriture de code qui a été écrit pour être compatible avec les types qu'ils utilisent.

Je pense que C pourrait peut-être mieux d'être considérée comme une recette pour la conversion des spécifications du système dans la langue de dialectes. Un système qui utilise de 36 bits, la mémoire ne sera pas vraiment en mesure de traiter efficacement le même dialecte du langage en tant que système d'utilisation de l'octet de mémoire, mais un programmeur qui apprend un dialecte serait en mesure d'apprendre à un autre simplement en apprenant ce que entier représentations de ce dernier qu'on utilise. Il est beaucoup plus utile de dire un programmeur qui a besoin d'écrire du code pour un 36-bit, "Cette machine est juste comme les autres machines, sauf char 9 bits, short est de 18 bits, et long est de 36 bits", que de dire "Vous devez utiliser langage d'assemblage, parce que les autres langues n'exigent tous les types integer, ce système ne peut pas traiter de manière efficace".

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