Opérateur sizeof de type tableau de longueur variable

Selon cppreference :

Si le type d’ expression est un type de tableau de longueur variable , l’ expression est évaluée et la taille du tableau auquel elle est évaluée est calculée au moment de l’exécution.

Cela signifie: si le type d’ expression est un type VLA, l’ expression est évaluée. Par exemple:

#include  int main() { int i = 0; int a[i]; printf("%zu\n",sizeof(a[i++])); printf("%d\n",i); // Here, print 0 instead of 1 return 0; } 

Donc, selon la référence, ici i deviens 1 . Mais, avec mon compilateur GCC, j’imprime en tant que 0 .

Voir la démo de Wandbox .

Tout d’abord, veuillez noter qu’un tableau ne peut pas avoir une taille nulle, qu’il s’agisse d’un VLA ou non. Votre code appelle donc un comportement indéfini.

C11 6.7.6.2/5

“Si la taille est une expression qui n’est pas une expression constante entière:” / – / “… chaque fois qu’elle est évaluée, sa valeur doit être supérieure à zéro.”


En ce qui concerne le problème actuel, a[i++] est de type int , pas de type VLA.

Pour obtenir l’effet secondaire, vous devez impliquer le type de tableau VLA, tel que sizeof(a) . Alors seulement, l’opérande est évalué pour les effets secondaires. Un exemple pour illustrer ceci:

 #include  int main() { int i=1, j=1; int a[i][j]; int b[1][1]; (void) sizeof(a[--i]); (void) sizeof(b[--j]); printf("%d %d", i, j); return 0; } 

Ici, i termine par 0 puisque le premier sizeof est évalué à cause du VLA, mais j rest 1 car --j faisait partie d’un sizeof pour un tableau régulier.

L’expression en sizeof dans votre exemple est int et non pas vla. Si c’était vla, tout fonctionnerait:

 #include  int main() { int i = 5; int a[i][i]; printf("%zu\n",sizeof(a[--i])); printf("%d\n",i); // Here, print 4 return 0; } 

Tiré de la norme C 6.5.3.4p2

L’opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d’un type. La taille est déterminée à partir du type de l’opérande. Le résultat est un entier. Si le type de l’opérande est un type de tableau de longueur variable, l’opérande est évalué. sinon, l’opérande n’est pas évalué et le résultat est une constante entière .

Dans l’expression:

 sizeof(a[i++]) 

le a[i++] n’est pas VLA, mais une expression d’opérateur en indice résultant en un entier. Ainsi, l’opérande n’est pas évalué et pour la même raison, le compilateur donne un avertissement sur cette instruction:

warning: expression with side effects has no effect in an unevaluated context

Pour prendre la parole d’un clone d’une référence normative pour cela:

6.5.3.4 – La taille des opérateurs et _Alignof

L’opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d’un type. La taille est déterminée à partir du type de l’opérande. Le résultat est un entier. Si le type de l’opérande est un type de tableau de longueur variable, l’opérande est évalué. sinon, l’opérande n’est pas évalué et le résultat est une constante entière.

Il serait évalué, si vous corrigez votre exemple pour produire une expression avec le type VLA, une telle manière

 #include  int main() { int i = 1; int a[5][i]; printf("%zu\n",sizeof(a[i++])); printf("%d\n",i); return 0; } 

Imprime 2 sur la dernière ligne , car i est incrémenté.