当前位置: C语言 -- 专题 -- restrict类型限定符

restrict类型限定符

restrict类型限定符(type qualifier)是ISO/IEC 9899:2018标准提供的4个类型限定符之一,restrict类型限定符仅用于对象指针,和其它3个类型限定符一样,restrict类型限定符仅对左值表达式才有意义。

使用restrict类型限定符限定的指针也称为受限指针(restricted pointer),受限指针与其指向对象之间存在着一种特殊关系:在受限指针的生命周期内,如果受限指针指向的对象发生改变,所有对该对象的访问(包括读和写)都必须直接地或者间接地通过受限指针来完成;否则其行为是未定义的。


下面结合具体例子来讨论一下这种特殊关系。

{
    int * restrict ptrOne;
    int * restrict ptrTwo;
    ...
}

在一个块中声明了两个受限指针ptrOneptrTwo,假设ptrOne指向一个对象,并且该对象在块中进行了修改;那么就不能使用ptrTwo访问该对象。


受限指针与指向对象之间的特殊关系并不是因为使用restrict类型限定符确定的,而是通过编程人员编写代码确定的;使用restrict类型限定符是告诉编译器这种关系,编译器可以在此基础上进行某些优化。

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
/* restrict类型限定符范例1 */

#include <stdio.h>
#include <stdlib.h>

#define LENGTH 5

int main(void)
{
    int arr[LENGTH] = {0};
    int *ptrOne = arr;
    int * restrict ptrTwo;

    ptrTwo = calloc(LENGTH, sizeof(int));
    if(ptrTwo == NULL)
        exit(EXIT_FAILURE);

    for(int i=0; i<LENGTH; ++i)
    {
        ptrOne[i] -= 1;
        arr[i] += 2;
        ptrOne[i] += 3;
        
        ptrTwo[i] -= 1;
        ptrTwo[i] += 3;
    }

    free(ptrTwo);
    
    return 0;
}

受限指针ptrTwo是访问动态内存的唯一方式,使用restrict类型限定符就是告诉编译器可以执行某些优化,例如:将ptrTwo[i] -= 1;语句以及ptrTwo[i] += 3;语句优化为ptrTwo[i] += 2;。指针ptrOne不能执行类似优化,因为指针ptrOne不是访问指向对象的唯一方式。

具体实现中,会不会根据restrict类型限定符进行优化,以及如何优化将由实现决定。


受限指针可以给非受限指针赋值;但受限指针间的赋值却是未定义行为,受限指针间的赋值有个例外就是:在嵌套块中,如果受限指针是由外向内赋值,其行为是允许的。

{
    int * restrict outerOne;
    int * restrict outerTwo;
    int *ptr;
    
    ptr = outerOne;             //合法。
    outerTwo = outerOne;        //未定义行为。
    
    {
        int * restrict inner = outerOne;    //合法。
    }
}