Un tableau peut-il avoir un remplissage final?

Il est clair que les tableaux en C ne peuvent pas insérer de remplissage entre leurs éléments . Cependant, y a-t-il une règle indiquant qu’ils ne peuvent pas append de remplissage à la fin du tableau dans son ensemble?

c’est-à-dire que ce programme est garanti pour donner les mêmes résultats partout?

#include  int main(void) { typedef char a[3]; typedef ab[3]; printf("%zu %zu\n", sizeof(a), sizeof(b)); // -> 3 9 } 

Pour autant que je sache, append un ou plusieurs octets de fin à la taille d’ a , peut-être dans une tentative d’optimisation peu judicieuse, n’enfreindrait pas les règles d’access au tableau ( b[1][1] toujours exactement à *(&b + sizeof(a) * 1 + 1) quelle que soit la taille de son contenu, a access au-delà de la longueur d’un contenu est de toute façon UB).

Je ne trouve nulle part dans la norme C où il est réellement indiqué que la taille d’un tableau est la taille du type d’élément multiplié par le nombre d’éléments. 6.5.3.4 dit seulement que sizeof renvoie le “nombre d’octets” dans le tableau (il donne comme exemple de code sizeof array / sizeof array[0] , mais ce n’est qu’un exemple – il ne dit pas que cela doit fonctionner , et cela ne donne aucun détail).

La garantie implicite est utile pour écrire du code portable qui dépend de la disposition exacte des données, par exemple en transmettant des valeurs RVB compressées:

 typedef uint8_t RGB[3]; RGB * data = ...; glColorPointer(3, GL_UNSIGNED_BYTE, 0, data); 

(OK, donc OpenGL peut accepter les valeurs ssortingde, donc c’est un mauvais exemple, mais vous obtenez le point.)

De ce fait, je suppose de la notion répandue (même à l’exemple de la norme) que vous pouvez obtenir le nombre d’éléments d’un tableau de sizeof , ce qui est susceptible de se produire partout de toute façon – existe-t-il des situations connues où n’est-ce pas?

Je pense qu’il n’a jamais été jugé nécessaire que le standard précise que les tableaux n’ont pas de remplissage, pour la simple raison qu’il n’y a absolument aucune raison pour que ce remplissage soit utile dans une implémentation quelconque.

Cela dit, je pense que la norme interdit ce type de remplissage à travers la description de l’opérateur == .

6.5.9 Opérateurs d’égalité

Sémantique

6 Deux pointeurs se comparent égaux si et seulement si […] ou l’un est un pointeur sur l’un après la fin d’un object tableau et l’autre sur un début d’object tableau différent qui suit immédiatement le premier tableau. object dans l’espace d’adressage.

Donné

 int array[2][2]; 

l’expression &array[0][2] est un pointeur situé au-delà de la fin du premier sous-object array. &array[1][0] est un pointeur sur le deuxième sous-object array, qui suit immédiatement le premier tableau en mémoire. Ces pointeurs sont nécessaires pour comparer égaux. Si int[2] avait un remplissage de fin, si sizeof(int[2]) > 2 * sizeof(int) , je ne peux imaginer comment une implémentation pourrait rendre les deux pointeurs comparables.