关于C语言中的restrict

原文地址:http://blog.sina.com.cn/s/blog_4f162ab60100e8pi.html

最近在搞Unix编程,,经常见到参数前面的restrict前缀,这文章解释得很清楚~~

 


 

补充一个APUE中的内容,即是restrict修饰符。下面一段引自Sun公司的技术文档:

  • restrict

    Objects referenced through a restrict-qualified pointer have a special association with that pointer. All references to that object must directly or indirectly use the value of this pointer. In the absence of this qualifier, other pointers can alias this object. Cacheing the value in an object designated through a restrict-qualified pointer is safe at the beginning of the block in which the pointer is declared, because no pre-existing aliases may also be used to reference that object. The cached value must be restored to the object by the end of the block, where pre-existing aliases again become available. New aliases may be formed within the block, but these must all depend on the value of the restrict-qualified pointer, so that they can be identified and adjusted to refer to the cached value. For a restrict-qualified pointer at file scope, the block is the body of each function in the file.

翻 译过来的意思就是,通过restrict限定的指针访问的对象与指针有一个特别的联系。所有对于那个对象的访问都必须要直接或者间接的用到这个指针的值。 倘若不存在restrict限定符,则其他指针可以作为这个对象的别名。如果有restrict修饰指针,则对于对象的值的缓冲在指针声明的代码块内是安 全的,因为没有别名用于引用这个对象。被缓冲的值在代码块结末的不分必须被回复,因为别名可能重新起效。块内可以声明其他的别名,但是这些必须基于 restrict修饰的指针的值,所以它们可以被调整为使用缓冲区内的值。对于文件域的restrict修饰符,restrict的作用域是文件的每个函 数体内部。

也就是说,比如我有一个内存中的对象,如果用restrict指针修饰,则使用的时候可以把它提到CPU的cache里面进行 处理(不懂硬件,大致意思应该是这样的吧),而不必担心其他指针引用了这个对象,而让它们没有取出正确的值来。最后cache内容还是要写回内存的。

restrict修饰符于1999年通过C标准


这里的restrict让我觉得有些疑惑,一查原来是C99中增加的关键字

那么restrict的意义是什么呢?

One of the new features in the recently approved C standard C99, is the restrict pointer qualifier. This qualifier can be applied to a data pointer to indicate that, during the scope of that pointer declaration, all data accessed through it will be accessed only through that pointer but not through any other pointer. The 'restrict' keyword thus enables the compiler to perform certain optimizations based on the premise that a given object cannot be changed through another pointer. Now you're probably asking yourself, "doesn't const already guarantee that?" No, it doesn't. The qualifier const ensures that a variable cannot be changed through a particular pointer. However, it's still possible to change the variable through a different pointer.

概括的说,关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。

举个简单的例子

int  foo ( int *  x,  int *  y)
{
*= 0;
*= 1;
return *x;
}


很显然函数foo()的返回值是0,除非参数x和y的值相同。可以想象,99%的情况下该函数都会返回0而不是1。然而编译起必须保证生成100%正确的代码,因此,编译器不能将原有代码替换成下面的更优版本

int  f ( int *  x,  int *  y)
{
*= 0;
*= 1;
return 0;
}

 

 

啊哈,现在我们有了restrict这个关键字,就可以利用它来帮助编译器安全的进行代码优化了

int  f ( int   * restrict x,  int   * restrict y)
{
*= 0;
*= 1;
return *x;
}


此时,由于指针 x 是修改 *x的唯一途径,编译起可以确认 “*y=1; ”这行代码不会修改 *x的内容,因此可以安全的优化为

int  f ( int   * restrict x,  int   * restrict y)
{
*= 0;
*= 1;
return 0;
}



最后注意一点,restrict是C99中定义的关键字,C++目前并未引入;在GCC可通过使用参数" -std=c99"
来开启对C99的支持

你可能感兴趣的:(REST)