Tome un vistazo a estas dos funciones:Orden de asignación de variables locales en la pila
void function1() {
int x;
int y;
int z;
int *ret;
}
void function2() {
char buffer1[4];
char buffer2[4];
char buffer3[4];
int *ret;
}
Si rompo en function1()
en gdb
, e imprimir las direcciones de las variables, me sale esto:
(gdb) p &x
$1 = (int *) 0xbffff380
(gdb) p &y
$2 = (int *) 0xbffff384
(gdb) p &z
$3 = (int *) 0xbffff388
(gdb) p &ret
$4 = (int **) 0xbffff38c
Si hago lo mismo en function2()
, me sale esto:
(gdb) p &buffer1
$1 = (char (*)[4]) 0xbffff388
(gdb) p &buffer2
$2 = (char (*)[4]) 0xbffff384
(gdb) p &buffer3
$3 = (char (*)[4]) 0xbffff380
(gdb) p &ret
$4 = (int **) 0xbffff38c
Notará que en ambas funciones, ret
se almacena más cerca de la parte superior de la pila. En function1()
, es seguido por z
, y
, y finalmente x
. En function2()
, ret
va seguido de buffer1
, luego buffer2
y buffer3
. ¿Por qué se cambia la orden de almacenamiento? Estamos utilizando la misma cantidad de memoria en ambos casos (4 bytes int
s frente a 4 bytes char
matrices), por lo que no puede ser un problema de relleno. ¿Qué razones podría haber para este reordenamiento, y además, es posible mirando el código C para determinar de antemano cómo se ordenarán las variables locales?
Ahora sé que la especificación ANSI para C no dice nada sobre el orden en que se almacenan las variables locales y que el compilador puede elegir su propio orden, pero me imagino que el compilador tiene reglas sobre cómo se ocupa de esto, y explicaciones de por qué esas reglas fueron hechas para ser como son.
Como referencia que estoy usando GCC 4.0.1 en Mac OS 10.5.7
¿es importante? ¿necesita las variables que se asignarán en una dirección específica? – stefanB
No, no es importante, es solo un ejercicio académico. – David
¿El nivel de optimización afecta la respuesta? Conjetura pura, pero tal vez sin optimización/baja, las entradas son candidatas para la asignación de registros, pero char [4] no lo es, y dado que se procesan de manera diferente, los dos mecanismos simplemente las ponen en la pila en diferentes órdenes. Incluso si la optimización no hace ninguna diferencia, es plausible que se maneje otra cosa en el modo automático, lo que significa que las entradas siempre bajan por una ruta y las matrices siempre por otra. –