Pourquoi les structures compactes ne font-elles pas partie du langage C?

10

Chaque compilateur C offre la possibilité de "pack" des structures C (par exemple __attribute__ ((__packed__)), ou #pragma pack()). Maintenant, nous savons tous que l'emballage est nécessaire, si nous voulons envoyer ou stocker des données de manière fiable. Cela doit également être une exigence depuis les premiers jours du langage C.

Je me demande donc pourquoi les structures compactées ne font pas partie de la spécification du langage C? Ils ne sont même pas en C99 ou C11 même si la nécessité de les avoir est connue depuis des décennies maintenant? Qu'est-ce qui me manque? Pourquoi est-il spécifique au compilateur?

grasbueschel
la source
2
Ils ne sont pas nécessaires pour écrire du code C pur.
user253751

Réponses:

7

Je suppose que c'est parce que cela dépend de la combinaison du processeur / compilateur cible utilisé. Cela signifie qu'il vaut mieux être une directive du compilateur (car elle est liée à cela) que l'aspect langage, car comment spécifier cela? La seule façon pour eux de le faire, c'est avec l'union.

L'article de Raymond donne un aperçu de la raison de cette situation: http://www.catb.org/esr/structure-packing/

Frans Bouma
la source
Article très intéressant. (+1)
Giorgio
Quelle difficulté y aurait-il à permettre au code de dire "J'ai besoin d'une structure contenant 12 octets; le champ X doit se comporter comme un entier de 32 bits stocké en quatre octets petit-boutien à l'offset 0; le champ Y doit se comporter comme un entier de 64 bits stocké en octets octets petit-boutien à un décalage de 4 "? Le code pour gérer cela sur n'importe quelle plate-forme ne devrait pas être pire que le genre de chose que les compilateurs doivent déjà faire pour les champs de bits, et dans les cas où le programmeur spécifie un alignement qui correspond à la machine native pourrait être beaucoup plus efficace. Sur d'autres machines, il serait moins efficace mais toujours portable.
supercat
5

Il y a trois facteurs principaux.

  1. Certains processeurs ne peuvent pas accéder aux données non alignées (par exemple un entier ou un flottant commençant sur une adresse impaire). Tenter de faire déclenche une exception.
  2. Certains processeurs peuvent accéder à des données non alignées, mais à un coût de performance.
  3. La plupart des structures sont accessibles par un seul ensemble de code source C / C ++, et l'interopérabilité avec d'autres langages est l'exception, pas la règle.

Avec ces facteurs à l'esprit, les compilateurs standard et tous les compilateurs C / C ++ remplissent régulièrement les structures pour assurer un alignement optimal pour le processeur, mais fournissent également des mécanismes pour le remplacer si nécessaire à des fins d'interopérabilité.

Ce n'est en aucun cas quelque chose qui a été négligé. Il est extrêmement bien compris et la situation actuelle est de par sa conception. Les dernières versions de la norme C ++ prennent en charge de manière approfondie la gestion des problèmes d'alignement, que vous ne connaissez peut-être pas.

david.pfx
la source
Tout argument qui pourrait être avancé contre des structures compactées pourrait également être utilisé pour justifier que les champs de bits soient une fonctionnalité facultative. L'accès aux membres des structures compressées serait lent sur certains processeurs, rapide sur d'autres, mais demander aux compilateurs d'essayer de remplacer les solutions de contournement du code utilisateur par le manque de fonctionnalités d'accès non aligné par du code plus efficace est beaucoup plus compliqué que de simplement laisser les compilateurs laisser les programmeurs spécifier ce que ils ont besoin.
supercat
@supercat: que défendez-vous (ou contre)? Je ne comprends pas.
david.pfx
Je suis d'avis que les champs de bits devraient être facultatifs, mais si les champs de bits doivent être une fonctionnalité obligatoire, il serait logique de les étendre de manière à permettre un contrôle explicite de la disposition des structures. Sinon, l'effet net est que les compilateurs doivent effectuer 90% du travail qui serait nécessaire pour un contrôle total de la mise en page, mais les programmeurs ne récoltent que 10% des avantages.
supercat
@supercat: les champs de bits sont des entiers et suivent les mêmes règles de classement de la disposition des bits que les entiers: implémentation définie. Les membres de la structure sont ordonnés sur les limites des caractères comme déclaré, éventuellement avec un emballage inséré. Ils sont conceptuellement assez séparés. [Vous devrez poser une autre question si vous souhaitez développer votre proposition, mais je ne pense pas que cela fonctionnerait du tout.]
david.pfx
0

Il est spécifique au compilateur car il n'est pas dans la norme. Et ce n'est pas dans la norme car il serait difficile de spécifier d'une manière qui ne nécessiterait pas beaucoup d'efforts de mise en œuvre pour les compilateurs de plates-formes obscures avec des restrictions d'alignement appliquées.

Et aucun de ces efforts n'a beaucoup de justification, car tous les compilateurs / plates-formes qui intéressent tous ceux qui utilisent un compilateur C89 ou ultérieur l'ont déjà implémenté.

Soru
la source
2
??? Vous avez répondu à la question "Pourquoi n'est pas dans la langue standard" en disant "parce que n'est pas dans la langue standard" ...
Emilio Garavaglia
C'est ce que je pensais en premier, mais là encore, on pourrait spécifier la fonctionnalité comme "si struct est défini avec le mot-clé 'packed', sa taille est garantie d'être la même que la taille ajoutée de chaque membre individuel. Sur les plateformes qui ne prennent pas en charge accès mémoire non aligné, l'accès à l'une des valeurs des membres struct est un comportement non défini. " Cela permettrait aux développeurs sur des plates-formes sans accès non aligné de connaître au moins la taille des structures et le décalage de chaque membre individuel ...
grasbueschel
1
Il serait possible de faire fonctionner l'accès non aligné sur des systèmes qui ne le prennent pas en charge en matériel en implémentant des structures telles qu'un tableau d'octets et en effectuant le décalage de bits et &/ les |opérations nécessaires pour lire / écrire les valeurs de chaque champ.
dan04
1
@ dan04: Sur de nombreux processeurs, un compilateur pouvait générer du code pour un accès non aligné qui était plus efficace que l'utilisation d'une séquence de lectures et de décalages d'octets. Avoir une syntaxe pour cela permettrait à ces compilateurs de générer plus facilement du code efficace que de les obliger à reconnaître toutes les différentes manières dont les programmeurs pourraient essayer d'écrire du code pour assembler des octets en types plus longs.
supercat