Existe-t-il des limites de taille pour les structures en C?

Existe-t-il des limites de taille pour les structures en C?

De la norme C:

5.2.4.1 Limites de traduction

1 L’implémentation doit être capable de traduire et d’exécuter au moins un programme contenant au moins une instance de chacune des limites suivantes:

… – 65 535 octets dans un object (dans un environnement hébergé uniquement)
… – 1023 membres dans une seule structure ou union
… – 63 niveaux de définitions de structure ou d’union nestedes dans une seule liste de struct-déclaration … 13) Les implémentations doivent éviter autant que possible d’imposer des limites de traduction fixes.

En dehors de cela, la limite supérieure est SIZE_MAX (valeur maximale pour size_t ).

Étant donné que l’opérateur sizeof size_t un résultat de type size_t , la limite doit être SIZE_MAX .

Vous pouvez déterminer la valeur de SIZE_MAX comme ceci:

 #include  #include  int main (void) { printf("%zu", SIZE_MAX); return 0; } 

C’est ce que le compilateur devrait autoriser. Ce que l’environnement d’exécution permet, c’est une autre histoire.

Déclarer un object de taille similaire sur la stack (localement) en pratique ne fonctionnera pas car la stack est probablement beaucoup, beaucoup plus petite que SIZE_MAX .

Avoir un tel object globalement pourrait amener le chargeur exécutable à se plaindre au démarrage du programme.

Analyse empirique

En pratique, des implémentations telles que GCC semblent n’autoriser que les structures inférieures à size_t , éventuellement liées par PTRDIFF_MAX . Voir aussi: Quelle est la taille maximale d’un tableau en C?

En utilisant:

  for i in `seq 32`; do printf "typedef struct { S$ix; S$iy; } S$(($i+1));\n"; done 

Nous faisons le programme:

 #include  #include  typedef struct { uint8_t i; } S0; typedef struct { S0 x; S0 y; } S1; typedef struct { S1 x; S1 y; } S2; typedef struct { S2 x; S2 y; } S3; typedef struct { S3 x; S3 y; } S4; typedef struct { S4 x; S4 y; } S5; typedef struct { S5 x; S5 y; } S6; typedef struct { S6 x; S6 y; } S7; typedef struct { S7 x; S7 y; } S8; typedef struct { S8 x; S8 y; } S9; typedef struct { S9 x; S9 y; } S10; typedef struct { S10 x; S10 y; } S11; typedef struct { S11 x; S11 y; } S12; typedef struct { S12 x; S12 y; } S13; typedef struct { S13 x; S13 y; } S14; typedef struct { S14 x; S14 y; } S15; typedef struct { S15 x; S15 y; } S16; typedef struct { S16 x; S16 y; } S17; typedef struct { S17 x; S17 y; } S18; typedef struct { S18 x; S18 y; } S19; typedef struct { S19 x; S19 y; } S20; typedef struct { S20 x; S20 y; } S21; typedef struct { S21 x; S21 y; } S22; typedef struct { S22 x; S22 y; } S23; typedef struct { S23 x; S23 y; } S24; typedef struct { S24 x; S24 y; } S25; typedef struct { S25 x; S25 y; } S26; typedef struct { S26 x; S26 y; } S27; typedef struct { S27 x; S27 y; } S28; typedef struct { S28 x; S28 y; } S29; typedef struct { S29 x; S29 y; } S30; /*typedef struct { S30 x; S30 y; } S31;*/ S30 s; int main(void) { printf("%jx\n", (uintmax_t)sizeof(s)); return 0; } 

puis à Ubunbu le 17.10:

 $ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ arm-linux-gnueabi-gcc -std=c99 main.c 

travaux. Mais si nous décommentons S31 , il échoue avec:

 main.c:35:16: error: type 'struct ' is too large typedef struct { S30 x; S30 y; } S31; 

La taille maximale est donc comprise entre 2 ^ 30 et (2 ^ 31 – 1).

Ensuite, nous pouvons convertir S30 en:

 typedef struct { S29 x; S29 y; uint8_t a[(2lu << 29) - 1]; } S30; 

et avec cela, nous déterminons que la taille maximale est en fait de 2^31 - 1 == PTRDIFF_MAX sur cette implémentation.