¿Typedef VLA requiere una evaluación de la expresión de tamaño?
int f(void); int main(void) { typedef int (T) [ f() ]; // is f required to be evaluated ? T x; return sizeof x; }¿El puntero typedef a VLA requiere evaluación de la expresión de tamaño?
int f(void); int main(void) { typedef int (*T) [ f() ]; // is f is required to be evaluated ? T x; return sizeof x; } UPD. En la definición de f es visible, entonces una llamada puede optimizarse:
int f(void) { return 4; } int main(void) { typedef int (*T) [ f() ]; return sizeof(T); }Código generado (tanto GCC como LLVM):
main: mov eax, 8 ret Se espera, porque no hay una necesidad real de llamar a f para determinar el tamaño de un puntero.
De acuerdo con el Estándar C ( §6.7.8 Definiciones de tipos )
3 En una declaración cuyo especificador de clase de almacenamiento es typedef, cada declarador define un identificador para que sea un nombre typedef que denota el tipo especificado para el identificador en la forma descrita en 6.7.6. Cualquier expresión de tamaño de matriz asociada con declaradores de matriz de longitud variable se evalúa cada vez que se alcanza la declaración del nombre typedef en el orden de ejecución.
Y hay un ejemplo en el estándar C
8 EJEMPLO 5 Si un nombre typedef denota un tipo de matriz de longitud variable, la longitud de la matriz se fija en el momento en que se define el nombre typedef, no cada vez que se usa:
void copyt(int n) { typedef int B[n]; // B is n ints, n evaluated now n += 1; B a; // a is n ints, n without += 1 int b[n]; // a and b are different sizes for (int i = 1; i < n; i++) a[i-1] = b[i]; }Aquí hay un programa de demostración.
#include <stdio.h> int f( void ) { static int n; return ++n; } void g( void ) { typedef int ( *T )[ f() ]; T p; printf( "sizeof( *p ) = %zu\n", sizeof( *p ) ); } int main(void) { for ( size_t i = 0; i < 10; i++ ) { g(); } }La salida del programa es
sizeof( *p ) = 4 sizeof( *p ) = 8 sizeof( *p ) = 12 sizeof( *p ) = 16 sizeof( *p ) = 20 sizeof( *p ) = 24 sizeof( *p ) = 28 sizeof( *p ) = 32 sizeof( *p ) = 36 sizeof( *p ) = 40