对C限制符号感到困惑

时间:2017-03-14 08:56:25

标签: c alias restrict

首先,cppreference有关于restrict的以下内容:

  

在每次执行声明受限指针P的块(通常每次执行P是函数参数的函数体)时,如果某个可通过P(直接或间接)访问的对象被修改,无论如何,那个块中对该对象的所有访问(包括读取和写入)都必须通过P(直接或间接)进行,否则行为是未定义的。

但是在这一段之下它说:

  

可以自由地将受限制的指针分配给不受限制的指针,只要编译器能够分析代码,优化机会就会保留到位:

void f(int n, float * restrict r, float * restrict s) {
   float * p = r, * q = s; // OK
   while(n-- > 0) *p++ = *q++; // almost certainly optimized just like *r++ = *s++
}

在上面,r[0]是一个可以通过限制指针r访问的对象,它可以通过p访问,这似乎与第一段(访问r[0]必须仅通过r)生效?

第二

  

从一个受限指针到另一个受限指针的赋值是未定义的行为,除非从指向某个外部块中的对象的指针指向某个内部块中的指针(包括在使用受限指针参数调用函数时使用受限指针参数) )或从函数返回时(否则当从指针的块结束时)。

那么,以下代码是否正常?

void foo(char* restrict a, size_t s)
{
    for(char* restrict aa = a; aa < a + s; ++aa) // Is aa in an inner block?
    {
        *aa = '\0';
    }
}

1 个答案:

答案 0 :(得分:2)

示例1中的关键是,用于访问transform : translateX(n%) 指向的基础数组的左值*p的地址基于r 。换句话说,它是通过r进行的间接访问。由于r的地址也基于*q,所有访问都会通过原始的限制指针间接发生:这里没有UB。

示例2更加微不足道。您在原始指针上声明了一个新的受限指针基于。所以也没有UB。但是在示例2中,两个受限限定符都没有添加任何值,因为在块内(s函数定义)只使用了一个单指针,因为foo基于aa

在示例1中,a限定符向编译器声明restrictr指向的数组不重叠:无法通过s(直接或间接访问)通过r)应触及p指向的数组。