C语言中关键字restrict的用法(linux 为 __restrict)

类型限定词restrict
关键字restrict通过允许编译器优化某几种代码增强了计算支持。它只可用于指针,并表明指针是访问一个数据对象的惟一且初始的方式。为了清楚这样做为何有用,我们需要看一些例子。考虑下面的代码:
int ar[10];
int * restrict restar = (int *) malloc(10 * sizeof(int));
int * par = ar;
这里,指针restar是访问由malloc()分配的内存的惟一且初始的方式。因此,它可以由关键字restrict限定。然而,par指针既不是初始的,也不是访问数组ar中数据的惟一方式,因此不可以把它限定为restrict。
现在考虑下面这个更复杂的例子,其中n是一个int:
for(n=0; n < 10; n++)
{
par[n] += 5;
restart[n] += 5;
ar[n] *= 2;
par[n] += 3;
restar[n] += 3;
}
知道了restar是访问它所指向数据块的惟一初始方式,编译器就可以用具有同样效果的一条语句来代替包含restar的两个语句:
restar[n] += 8;
然而,将两个包含par的语句精简为一个语句将导致计算错误:
par[n] += 8;
出现错误结果的原因是循环在par两次访问同一个数据之间,使用ar改变了该数据的值。
没有关键字restrict,编译器将不得不设想比较糟的那种情形,也就是两次使用指针之间,其他标识符可能改变了数据的值。使用restrict关键字之后,编译器可以放心地寻找计算的捷径。
可以将关键字restrict作为指针型函数参量的限定词使用。这意味着编译器可以假定在函数体内没有其他标识符修改指针指向的数据,因而可以试着优化代码,反之则不然。例如,C库中有两个函数可以从一个位置把数据复制到另一个位置。在C99标准下,他们的原型如下:
void * memcpy(void * restrict dst, const void * restrict src, size_t n);
void * memmove(void * dst, const void * src, size_t n);
两个函数都从位置src把n个字节复制到dst中。函数memcpy()要求两个位置之间不重叠,但memmove()没有这个要求。把dst和src声明为restrict意味着每个指针都是相应数据的惟一访问方式,因此他们不能访问同一数据块。这满足了不能有重叠的要求。函数memmove()允许重叠,它不得不在复制数据时更加小心,以防在使用数据前就覆盖了数据。
关键字restrict有两个读者。一个是编译器,它告诉编译器可以自由地做一些有关优化的假定。 另一个读者是用户,它告诉用户仅使用满足restrict要求的参数。 一般,编译器无法检查您是否遵循了这一限制,如果您蔑视它也就是在让自己冒险。
(以上大部分内容摘自《C Primer Plus》)
  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值