簡介
restrict是c99標(biāo)準(zhǔn)引入的喘蟆,它只可以用于限定和約束指針,并表明指針是訪問一個(gè)數(shù)據(jù)對(duì)象的唯一且初始的方式.即它告訴編譯器逻住,所有修改該指針?biāo)赶騼?nèi)存中內(nèi)容的操作都必須通過該指針來修改,而不能通過其它途徑(其它變量或指針)來修改;這樣做的好處是,能幫助編譯器進(jìn)行更好的優(yōu)化代碼,生成更有效率的匯編代碼.
由restrict修飾的指針主要用于函數(shù)形參梭冠,或指向由malloc()分配的內(nèi)存空間呕寝。
通過GCC生成匯編指令的例子來更好的理解這個(gè)關(guān)鍵字
-
沒有restrict關(guān)鍵字聲明的代碼
void f(int *a, int *b, int *c)
{
*a += *c;
*b += *c;
}
將以上代碼寫入文件code.c空执,通過終端(terminal)中輸入
gcc -O2 -S code.c -o code.s
注意:“-O2”中的O以及“-S”中的S需要大寫
生成的code.s文件內(nèi)容如下:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 11
.globl _f
.align 4, 0x90
_f: ## @f
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp0:
.cfi_def_cfa_offset 16
Ltmp1:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp2:
.cfi_def_cfa_register %rbp
movl (%rdx), %eax
addl %eax, (%rdi)
movl (%rdx), %eax
addl %eax, (%rsi)
popq %rbp
retq
.cfi_endproc.subsections_via_symbols
其中關(guān)鍵的匯編指令為:
movl (%rdx), %eax
addl %eax, (%rdi)
movl (%rdx), %eax
addl %eax, (%rsi)
- 再看看有restrict關(guān)鍵字聲明的代碼
void f(int * restrict a, int* restrict b, int* restrict c)
{
*a += *c;
*b += *c;
}
通過上面一樣的步驟生成匯編指令如下:
movl (%rdx), %eax
addl %eax, (%rdi)
addl %eax, (%rsi)
相較沒有加restrict關(guān)鍵字聲明的情況浪箭,優(yōu)化了第二步的指針c加載。
總結(jié)
restrict關(guān)鍵字聲明主要是幫助編譯器更好的進(jìn)行代碼優(yōu)化辨绊,實(shí)際上并不影響代碼的寫法奶栖。