So, I recently took an interest in how well the compiler (gcc (GCC) 4.8.3
being the one in question) is in optimizing pointers and pointers.
Initially I created a simple integer and an integer pointer and realized operations on it so I could print it out. As expected, all the operations that were hard coded were optmized, through dereferenced pointer or not.
call __main
leaq .LC0(%rip), %rcx
movl $1, %edx
call printf
And even after creating a function that takes in an int pointer, dereferences it and changes it it still was perfectly optmized.
call __main
leaq .LC0(%rip), %rcx
movl $-1, %edx
call printf
Now, when I treated my pointer as a void and made changes by casting it to char and dereferencing it, it actually still optmized perfectly (an 'extra' mov call since I initially treated it as an 8 byte value, and then as a 1 byte value for pointer dereferencing)
call __main
movl $4, 44(%rsp)
movb $2, 44(%rsp)
leaq .LC0(%rip), %rcx
movl 44(%rsp), %eax
leal 1(%rax), %edx
call printf
So onto my question(s):
How consistent is compiler optimization regarding pointer dereferencing? What would be some cases where it would chose to be conservative?
If all of my pointers in a project were declared with the restrict keyword, could I trust it would be as well optimized as if 'no pointers were being used at all'?
(assuming there are no volatile
cases )
Ps¹.: I am aware the compiler generally does a good enough job, and that a programmer worrying about aiding the compiler in minor optimizations is, in general, unproductive (as so many point out in stackoverflow answers to questions regarding optimization). Yet I still have curiosity regarding the matter.
Ps².: gcc -O3 -S -c main.c
was the command used to generate the assembly code
C Code: (as requested)
1:
#include <stdio.h>
int main (void)
{
int a = 4;
int *ap = &a;
*ap = 0;
a += 1;
printf("%d\n", a);
return 0;
}
2:
#include <stdio.h>
void change(int *p) {
*p -= 2;
}
int main (void)
{
int a = 4;
int *ap = &a;
*ap = 0;
change(ap);
a += 1;
printf("%d\n", a);
return 0;
}
3:
#include <stdio.h>
void change(void *p) {
*((char*)p) += 2;
}
int main (void)
{
int a = 4;
void *ap = (void*) &a;
*((char*)(ap)) = 0;
change(ap);
a += 1;
printf("%d\n", a);
return 0;
}