Sizeof mira el tipo de expresión que se le da, no evalúa la expresión. Por lo tanto, solo necesita asegurarse de que las variables utilizadas en la expresión estén declaradas para que el compilador pueda deducir su tipo.
En su ejemplo, st ya está declarado como pointer-to-struct-retValue. En consecuencia, el compilador puede deducir el tipo de la expresión "* st".
Aunque no parezca que ya está declarada en el código, el compilador ya se ha hecho cargo de él para usted. Todas las declaraciones en su código se mueven al comienzo del bloque en el que ocurren por el compilador. Supongamos que escribe
Una forma de ilustrar el conocimiento que está disponible para el compilador es mirar a la salida intermedia que genera. Considere este ejemplo de código ...
struct retValue {long int a, long int b};
...
printf("Hello World!\n");
struct retValue* st = malloc(sizeof(*st));
con gcc como un ejemplo y teh código anterior en el principal() función de test.c, vamos a ver la salida intermedia mediante la ejecución ...
gcc -fdump-tree-cfg test.c
el compilador generará el archivo test.c.022t.cfg - vistazo y verá
[ ... removed internal stuff ...]
;; Function main (main)
Merging blocks 2 and 3
main (argc, argv)
{
struct retValue * st;
int D.3097;
void * D.3096;
# BLOCK 2
# PRED: ENTRY (fallthru)
__builtin_puts (&"Hello World!"[0]);
D.3096 = malloc (16);
st = (struct retValue *) D.3096;
D.3097 = 0;
return D.3097;
# SUCC: EXIT
}
Observe cómo la declaración se movió al principio del bloque y el argumento a malloc ya se reemplazó con el valor real que denota el tamaño del tipo en que se evalúa la expresión. Como se señaló en los comentarios, el hecho de que la declaración se movió a la parte superior del bloque es un detalle de implementación del compilador. Sin embargo, el hecho de que el compilador sea capaz de hacer esto y de insertar el tamaño correcto en el malloc muestra que el compilador pudo deducir la información necesaria de la entrada.
yo personalmente prefiero dar el nombre de tipo real como un parámetro a sizeof, pero eso es probablemente una cuestión de estilo de codificación, donde yo diría que la consistencia triunfos personales-preferencia.
Respondió su propia pregunta. sizeof (struct retValue) es correcto –
Lo siento, la pregunta no era '¿Es correcto o qué es correcto?' era '¿Por qué funciona esto?' – Blackbinary
Podría ayudar entender si cambia la terminología. No estás * definiendo * una estructura usando malloc, estás * asignando * una estructura usando malloc. Está definiendo 'st', que es un puntero (no una estructura). Ese puntero ya está definido y disponible para su uso en la expresión del inicializador (en el RHS del signo igual), simplemente no tiene un valor, por lo que la mayoría de los usos no serían válidos. Este está bien, sin embargo, porque sizeof no usa el valor. –