69,374
社区成员
发帖
与我相关
我的任务
分享
int fun(int *a, int *b)
{
*a = 5;
*b = 6;
return *a + *b; //不一定返回11
}
如果指针a和指针b指向同一个对象,*b = 6会导致 *a为6,返回12.所以编译器在做return *a + *b 的时候需要重新读取*a 的值。
fun:
movl $5,(%rdi) #存储5到*a
movl $6,(%rsi) #存储6到*b
movl (%rdi),%eax #重新读取*a
addl $6,%eax #加上6
ret
如果我们确保两个指针不会指向同一个对象,则可以使用restrict修饰指针变量
int rfun(int *restrict a, int *restrict b)
{
*a = 5;
*b = 6;
return *a + *b;
}
编译器可以根据这个信息做优化
rfun:
movl $11,%eax #在编译期就可以计算出11
movl $5,(%rdi) #存储5到*a
movl $6,(%rsi) #存储6到*b
ret
总而言之,restrict是为了告诉编译器指针独享指针所指向的内存,从而编译器能生成更优化的机器码。编译器是无法检测指针是否独享指针指向内存的,所以如果程序员使用restrict,那么程序员也需要遵守相应的契约保证才能得出正确的代码,否则,行为是未定义的。
int fun(int *a, int *b)
{
*a = 5;
*b = 6;
return *a + *b; //不一定返回11
}
如果指针a和指针b指向同一个对象,*b = 6会导致 *a为6,返回12.所以编译器在做return *a + *b 的时候需要重新读取*a 的值。
fun:
movl $5,(%rdi) #存储5到*a
movl $6,(%rsi) #存储6到*b
movl (%rdi),%eax #重新读取*a
addl $6,%eax #加上6
ret
如果我们确保两个指针不会指向同一个对象,则可以使用restrict修饰指针变量
int rfun(int *restrict a, int *restrict b)
{
*a = 5;
*b = 6;
return *a + *b;
}
编译器可以根据这个信息做优化
rfun:
movl $11,%eax #在编译期就可以计算出11
movl $5,(%rdi) #存储5到*a
movl $6,(%rsi) #存储6到*b
ret
总而言之,restrict是为了告诉编译器指针独享指针所指向的内存,从而编译器能生成更优化的机器码。编译器是无法检测指针是否独享指针指向内存的,所以如果程序员使用restrict,那么程序员也需要遵守相应的契约保证才能得出正确的代码,否则,行为时未定义的。