Comment sizeof (array) fonctionne-t-il à l’exécution?

J’ai lu que l’opérateur sizeof en C est interprété au moment de la compilation et puisque, à la compilation, le compilateur connaît la taille du tableau et son type, sizeof permet de calculer le nombre d’octets occupés par array.But comment sizeof fonctionne pour le code suivant:

#include #include int main() { int n; scanf("%d",&n); int a[n]; int s=sizeof(a); printf("%d",s); return 0; } 

Ici, la taille du tableau n’est pas connue au moment de la compilation, alors comment fonctionne-t-il correctement?

sizeof est toujours calculé lors de la compilation en C89. Depuis C99 et les tableaux de longueur variable, il est calculé au moment de l’exécution lorsqu’un tableau de longueur variable fait partie de l’expression dans l’opérande sizeof .

Idem pour l’évaluation de l’opérande sizeof : il n’est pas évalué en C89 mais en C99 si l’opérande est de type tableau de longueur variable, il est évalué. Par exemple:

 int n = 5; sizeof (int [n++]); // n is now 6 

Etant donné que vous appliquez sizeof à un tableau de longueur variable, dont la taille n’est pas complètement connue au moment de la compilation, le compilateur doit générer du code pour pouvoir en effectuer une partie au moment de l’exécution.

Les optimiseurs de haut niveau de gcc 4.6.3 convertissent le code que vous avez montré

 scanf ("%d", &n); t12 = (long unsigned int) n; t13 = t12 * 4; __builtin_alloca (t13); t16 = (unsigned int) t12; t17 = t16 * 4; s18 = (int) t17; printf ("%d", s18); 

Est-ce que cela explique ce qui se passe sous le capot? (Ne soyez pas rebutés par le nombre ridicule de variables temporaires – c’est un artefact du programme qui se présente sous la forme d’ une seule affectation statique au moment où j’ai demandé un vidage de code intermédiaire.)

De la norme C99:

6.5.3.4

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.

J’ai lu que l’opérateur sizeof en C est interprété à la compilation

sizeof taille deofof est déterminée au moment de la compilation dans tous les cas sauf pour les VLA. Pour un VLA, sizeof est évalué à l’exécution.

Dans ce cas, sizeof() est évalué au moment de l’exécution. Le compilateur, car il sait que la taille de a est basée sur la valeur de n au moment de la déclaration du tableau, génère du code qui utilise la valeur appropriée de n pour renvoyer une valeur raisonnable pour sizeof() .

En C99, toutes les utilisations de sizeof() ne peuvent pas être complètement évaluées au moment de la compilation et réduites à une constante d’exécution.

Indépendamment du fait que sizeof soit calculé lors de la compilation ou de l’exécution (ou plus officiellement, si son résultat est une expression constante entière), le résultat de sizeof est purement basé sur le type de son argument et non sur les données cachées accompagnant la longueur variable. tableau lui-même. Bien sûr, lorsque sizeof est appliqué à un type à modification variable, le programme généré doit garder trace de cette taille quelque part. Mais il pourrait simplement la recalculer si l’expression était suffisamment simple et que les variables dont elle a dérivé la longueur ne peuvent pas avoir changé. Ou bien, il pourrait stocker la taille du type quelque part (essentiellement dans une variable locale masquée), mais cela ne serait pas connecté à l’object VLA de manière observable (par exemple, si vous passez un pointeur sur le premier élément de VLA pour une autre fonction, ce pointeur ne peut pas être utilisé pour récupérer la longueur de VLA).