Let's say I have the global array
char global_array[3] = {33, 17, 6};
and I access global_array[1]
. When gcc interprets global_array[1]
, will it add 1 to the address of global_array
at runtime, or change global_array[1]
to a static address, assuming -O0? If not, is there a compiler flag to for gcc to make the static index of an array a static pointer?
When gcc interprets global_array[1], will it add 1 to the address of global_array at runtime, or change global_array[1] to a static address, assuming
-O0
?
There's no particular guarantees of what gcc does and does not depending on level of optimization. Take your example under gcc 12.2 for x86_64:
int func (void)
{
char global_array[3] = {33, 17, 6};
return global_array[1];
}
This results in peculiar assembly code under -O0
:
func:
push rbp
mov rbp, rsp
mov WORD PTR [rbp-3], 4385
mov BYTE PTR [rbp-1], 6
movzx eax, BYTE PTR [rbp-2]
movsx eax, al
pop rbp
ret
It is storing the array of the stack but it loads the magic number 4385 as a word, then loads a 6 at the end. Now wth is 4385? It is 0x1121 hex. Where the bytes have values 0x11 = 17dec and 0x21 = 33, and since it is a x86 little endian, the byte order for the WORD
instruction is reversed vs the order of the array.
This word write is already some manner of mini-optimization even though I used -O0
. So again - no guarantees. Regarding your question, the access part rbp-2
is indeed similar to adding 1 the to the address in runtime. In this case it is subtracting an offset from the stack frame pointer, but that's essentially the same thing (and likely as fast/slow as adding 1 to an address).
The normal thing when optimizations are enabled would otherwise be to replace the whole thing with the absolute value.
If not, is there a compiler flag to for gcc to make the static index of an array a static pointer?
Messing around with compiler options is probably not how. If you wish to have a pointer to a fixed address, then this is the usual steps:
&global_array[1]
is always the same address.