30 votes

La norme C exige-t-elle que la taille d'un tableau de n éléments soit égale à n fois la taille d'un élément ?

Est-ce que la norme C exige que la taille d'un tableau de n les éléments sont n fois la taille d'un élément, soit par déclaration explicite, soit par déduction logique rigoureuse à partir de ses exigences ?

Par exemple, est-ce que int (*x)[5] = malloc(5 * sizeof **x); ne demande pas suffisamment d'espace pour un tableau de cinq int ?

C 2011 [N1570] 6.5.3.4 7 montre un exemple de calcul du nombre d'éléments d'un tableau sous forme de sizeof array / sizeof array[0] . Cependant, les exemples ne constituent pas une partie normative de la norme (selon le paragraphe 8 de l'avant).

6.2.5 20 dit qu'un type de tableau décrit un ensemble non vide alloué de manière contiguë d'objets d'un type particulier mais ne dit rien sur la mémoire totale requise.

Il s'agit uniquement d'une question de droit du langage ; les implémentations réelles ne sont pas pertinentes. (Pour apaiser ceux qui veulent des exemples concrets, faites l'hypothèse d'une implémentation C qui nécessite une gestion supplémentaire de la mémoire pour les grands tableaux, de sorte que la création d'un tableau nécessite la création de quelques données supplémentaires pour aider à gérer la mémoire).

22voto

David Bowling Points 9830

Oui, il est requis que la taille d'un tableau T[n] être n * sizeof (T) .

La norme définit les tableaux en §6.2.5/20 :

Un type de tableau décrit un ensemble non vide d'objets alloués de manière contiguë avec un type d'objet membre particulier.....

En outre, le sizeof L'opérateur donne le nombre total d'octets dans le tableau ( §6.5.3.4/4 ):

Quand taille de est appliqué .... à une opérande de type tableau, le résultat est le nombre total d'octets dans le tableau. Lorsqu'elle est appliquée à une opérande de type structure ou union, le résultat est le nombre total d'octets d'un tel objet, y compris le remplissage interne et arrière.

Comme un tableau est constitué d'une allocation contiguë d'objets, il ne peut y avoir de remplissage interne. Et puisque le rembourrage de fin de tableau est mentionné explicitement en ce qui concerne l'élément sizeof opérateur uniquement dans le contexte des unions et des structures, il semble clair que les tableaux ne doivent pas posséder un tel remplissage de fin.

Enfin, notez que dans §6.2.6.1/4 est déclaré :

Les valeurs stockées dans les objets sans champ de bits de tout autre type d'objet sont constituées de n x CHAR_BIT bits, où n est la taille d'un objet de ce type, en octets. La valeur peut être copiée dans un objet de type char non signé [ n ] (par exemple, par memcpy) ; l'ensemble d'octets résultant est appelé le représentation des objets de la valeur.

Supposons que les tableaux pourrait ont des octets de remplissage à la fin, considérez un tableau unsigned char A[n] et on considère en outre le tableau unsigned char B[sizeof A] vers lequel tous les octets (y compris les éventuels octets de remplissage) de A[] ont été copiés. Maintenant, A[] doit être de la même taille que B[] puisque ( §6.2.6.1/8 ):

Lorsqu'un opérateur est appliqué à une valeur qui a plus d'une représentation d'objet, la représentation d'objet utilisée ne doit pas affecter la valeur du résultat.

Cela signifie que B[] doit n'ont pas de remplissage de fin, ce qui signifie que les tableaux peuvent avoir des octets de remplissage de fin, sauf dans certaines conditions particulières qui ne sont mentionnées nulle part dans la norme, ou encore que les tableaux peuvent avoir un remplissage de fin, sauf pour les tableaux de unsigned char . Étant donné qu'aucune de ces possibilités n'est mentionnée dans la norme, il semble raisonnable de conclure que les tableaux ne doivent pas avoir de remplissage de fin en premier lieu.

11voto

R.. Points 93718

Le seul texte décrivant la représentation des tableaux est assez laconique, et se trouve dans ce que vous avez trouvé en 6.2.5 ¶20 :

Un nombre quelconque de types dérivés peut être construit à partir des types d'objets et de fonctions, comme suit :

  • Un type de tableau décrit un ensemble non vide d'objets alloués de manière contiguë avec un type d'objet membre particulier, appelé type d'élément. Le type d'élément doit être complet chaque fois que le type de tableau est spécifié. Les types de tableaux sont caractérisés par leur type d'élément et par le nombre d'éléments du tableau. On dit qu'un type de tableau est dérivé de son type d'élément, et si son type d'élément est T , le type de tableau est parfois appelé ''tableau de T''. La construction d'un type de tableau à partir d'un type d'élément est appelée ''dérivation de type de tableau''.

Notez qu'il ne dit pas quelque chose comme "ensemble non vide d'objets alloués de manière contiguë et remplissage", donc le tableau est seulement les objets. Ainsi, il semble qu'il n'y ait pas de base pour une affirmation selon laquelle sizeof le tableau [type] pourrait donner tout autre résultat que la taille de l'ensemble contigu d'objets, ce qui est évidemment N fois la taille du type d'élément individuel.

Il est également intéressant de noter que le remplissage n'est pas quelque chose qui peut simplement exister par lui-même parce qu'il n'est pas spécifié qu'il n'existe pas. C spécifie les représentations des types (6.2.6) et spécifie explicitement la possibilité de remplissage des bits et des octets lorsque cela est approprié. Il n'y a pas de texte sur le remplissage des tableaux, et il ne fait donc pas partie de leur représentation.

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