¿Cómo funciona sizeof(array) en tiempo de ejecución?
size of array python (6)
He leído que el operador sizeof en C se interpreta en tiempo de compilación y como el compilador en tiempo de compilación sabe el tamaño de la matriz y su tipo, sizeof puede calcular el número de bytes ocupados por la matriz. Pero, ¿cómo funciona sizeof para el siguiente código?
#include<stdio.h>
#include<string.h>
int main()
{
int n;
scanf("%d",&n);
int a[n];
int s=sizeof(a);
printf("%d",s);
return 0;
}
Aquí el tamaño de la matriz no se conoce en el momento de la compilación, entonces, ¿cómo funciona correctamente?
He leído que el operador sizeof en C se interpreta en tiempo de compilación
sizeof
se determina en el momento de la compilación en todos los casos, excepto para los VLA. Para un VLA, sizeof
se evalúa en tiempo de ejecución.
Dado que está aplicando sizeof
a una matriz de longitud variable, cuyo tamaño no se conoce completamente en el momento de la compilación, el compilador debe generar código para hacer parte de él en tiempo de ejecución.
Los optimizadores de alto nivel de gcc 4.6.3 convierten el código que mostró a
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);
¿Eso explica lo que está pasando bajo el capó? (No se deje intimidar por la cantidad de variables temporales que parecen ridículas: ese es un elemento del programa que se encuentra en forma de asignación única estática en el punto en el que pedí un volcado de código intermedio).
De la norma C99:
El operador sizeof
produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. El tamaño se determina a partir del tipo de operando. El resultado es un entero. Si el tipo del operando es un tipo de matriz de longitud variable, se evalúa el operando ; de lo contrario, el operando no se evalúa y el resultado es una constante entera.
En ese caso, sizeof()
se evalúa en tiempo de ejecución. El compilador, porque sabe que el tamaño de a
se basa en el valor de n
en el momento de la declaración de matriz, genera código para usar el valor apropiado de n
para devolver un valor razonable para sizeof()
.
En C99, no todos los usos de sizeof()
pueden evaluarse completamente en tiempo de compilación y reducirse a una constante de tiempo de ejecución.
Independientemente de si sizeof
se calcula en tiempo de compilación o en tiempo de ejecución (o más formalmente hablando, si su resultado es una expresión constante entera), el resultado de sizeof
se basa puramente en el tipo de su argumento y no en ningún dato oculto que acompañe a la variable de longitud propia matriz. Por supuesto, cuando se aplica sizeof
a un tipo modificado de forma variable, el programa generado debe realizar un seguimiento de ese tamaño en algún lugar. Pero podría simplemente volver a calcularlo si la expresión era lo suficientemente simple y las variables de las que derivó originalmente la longitud no pueden haber cambiado. O bien, podría almacenar el tamaño del tipo en algún lugar (esencialmente en una variable local oculta), pero esto no estaría conectado al objeto VLA de ninguna manera observable (por ejemplo, si pasa un puntero al primer elemento del VLA). a otra función, ese puntero no se puede usar para recuperar la longitud del VLA).
sizeof
siempre se calcula en tiempo de compilación en C89. Dado que C99 y las matrices de longitud variable, se calculan en el tiempo de ejecución cuando una matriz de longitud variable es parte de la expresión en el sizeof
operando.
Lo mismo para la evaluación del sizeof
operando: no se evalúa en C89 sino en C99 si el operando es de tipo de matriz de longitud variable, se evalúa. Por ejemplo:
int n = 5;
sizeof (int [n++]);
// n is now 6