Si consideri il seguente programma:Il compilatore è autorizzato a ottimizzare l'utilizzo della memoria dello stack riordinando le variabili locali?
#include <stdio.h>
void some_func(char*, int*, char*);
void stack_alignment(void) {
char a = '-';
int i = 1337;
char b = '+';
some_func(&a, &i, &b); // to prevent the compiler from removing the local variables
printf("%c|%i|%c", a, i, b);
}
Si genera il seguente assemblaggio (commenti aggiunto da me, io sono un novizio completo per il montaggio):
$ vim stack-alignment.c
$ gcc -c -S -O3 stack-alignment.c
$ cat stack-alignment.s
.file "stack-alignment.c"
.section .rdata,"dr"
LC0:
.ascii "%c|%i|%c\0"
.text
.p2align 2,,3
.globl _stack_alignment
.def _stack_alignment; .scl 2; .type 32; .endef
_stack_alignment:
LFB7:
.cfi_startproc
subl $44, %esp
.cfi_def_cfa_offset 48
movb $45, 26(%esp) // local variable 'a'
movl $1337, 28(%esp) // local variable 'i'
movb $43, 27(%esp) // local variable 'b'
leal 27(%esp), %eax
movl %eax, 8(%esp)
leal 28(%esp), %eax
movl %eax, 4(%esp)
leal 26(%esp), %eax
movl %eax, (%esp)
call _some_func
movsbl 27(%esp), %eax
movl %eax, 12(%esp)
movl 28(%esp), %eax
movl %eax, 8(%esp)
movsbl 26(%esp), %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
addl $44, %esp
.cfi_def_cfa_offset 4
ret
.cfi_endproc
LFE7:
.def _some_func; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
Come potete vedere ci sono 3 locali variabili (a
, i
e b
) con le dimensioni di 1 byte, 4 byte e 1 byte. Compreso il padding questo sarebbe 12 byte (assumendo che il compilatore si allinea a 4 byte).
Non sarebbe più efficiente la memoria se il compilatore modificasse l'ordine delle variabili in (a
, b
, i
)? Quindi sarebbero necessari solo 8 byte.
Qui una rappresentazione "grafico":
3 bytes unused 3 bytes unused
vvvvvvvvvvv vvvvvvvvvvv
+---+---+---+---+---+---+---+---+---+---+---+---+
| a | | | | i | b | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+
|
v
+---+---+---+---+---+---+---+---+
| a | b | | | i |
+---+---+---+---+---+---+---+---+
^^^^^^^
2 bytes unused
è il compilatore permesso di fare questa ottimizzazione (dal ecc serie C)?
- Se no (come penso l'uscita dell'assieme mostra), perché?
- Se sì, perché non succede sopra?
Supponendo che sia consentito dagli standard ecc, allora sarebbe completamente fino alla singola implementazione del compilatore, indipendentemente dal fatto che lo facciano o no. Immagino che sarebbe controllato dai livelli di ottimizzazione in fase di compilazione. – John3136
Il compilatore/ottimizzatore è libero di posizionare i locali dove lo desidera, purché non interrompa il programma. È libero di posizionare due variabili nello stesso posto se è sicuro che non vengano mai utilizzate contemporaneamente. – mah
Hai provato a compilare con diverse opzioni di ottimizzazione? Forse hai compilato le ottimizzazioni. –