所以,我最近感興趣的是編譯器(gcc (GCC) 4.8.3
是否是有問題的)在優化指針和指針方面的表現。編譯器何時會對指針解引用優化保守?
最初我創建了一個簡單的整數和一個整數指針,並且實現了 操作,所以我可以打印出來。正如預期的那樣,硬編碼的所有操作 都是通過取消引用指針來優化的。
call __main
leaq .LC0(%rip), %rcx
movl $1, %edx
call printf
甚至創建一個函數,它在一個int指針, 取消引用它,改變它,它仍然是完全optmized後。
call __main
leaq .LC0(%rip), %rcx
movl $-1, %edx
call printf
現在,當我處理我的指針爲無效,鑄造它爲char和提領它所做的更改 ,它實際上仍optmized 完美(一個「額外」的MOV呼叫,因爲我最初把它作爲一個8字節 值,然後作爲指針廢棄1個字節值)
call __main
movl $4, 44(%rsp)
movb $2, 44(%rsp)
leaq .LC0(%rip), %rcx
movl 44(%rsp), %eax
leal 1(%rax), %edx
call printf
所以到我的問題(S):
關於指針取消引用的編譯器優化的一致性如何?在某些情況下,它會選擇保守?
如果項目中的所有指針都是用restrict關鍵字聲明的,我可以相信它會像'完全沒有指針被使用'一樣優化嗎?
(假設沒有volatile
例)
Ps¹:我知道,編譯器一般不工作不夠好,那一個 程序員擔心在不重要的優化幫助編譯器,在 一般來說,非生產性的(因爲很多關於優化的問題在關於 問題的答案中指出)。然而,我仍然對此事有好奇心。
Ps².: gcc -O3 -S -c main.c
是用於生成彙編代碼
C代碼的命令:(如需要)
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;
}
'restrict'和'const'是程序員的保證,而不是編譯器。如果你違反合同,不要驚訝地調用UB – Olaf
爲什麼不包括C代碼,你得到了你發佈的結果彙編? –
@JimBuck我將它們附加到問題中。 – SSWilks