Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about C restrict qualifier

Tags:

c

alias

restrict

First, cppreference has the following to say about restrict:

During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined.

But below this paragraph it says:

Restricted pointers can be assigned to unrestricted pointers freely, the optimization opportunities remain in place as long as the compiler is able to analyze the code:

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++
}

In the above, r[0] is an object that is accessible through restricted pointer r, and it is getting accessed through p, which seems to contradict the first paragraph (that accesses to r[0] must occur solely through r) ?

Second:

Assignment from one restricted pointer to another is undefined behavior, except when assigning from a pointer to an object in some outer block to a pointer in some inner block (including using a restricted pointer argument when calling a function with a restricted pointer parameter) or when returning from a function (and otherwise when the block of the from-pointer ended).

So, is the following code ok?

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';
    }
}
like image 373
user2711115 Avatar asked Mar 14 '17 08:03

user2711115


People also ask

What is restrict type qualifier in C?

The restrict qualifier can be used in the declaration of a structure member. A compiler can assume, when an identifier is declared that provides a means of access to an object of that structure type, that the member provides the sole initial means of access to an object of the type specified in the member declaration.

What is restrict type qualifier?

The restrict (or __restrict or __restrict__ ) 1 type qualifier is an indication to the compiler that, if the memory addressed by the restrict -qualified pointer is modified, no other pointer will access that same memory.

What does __ restrict mean in C?

In the C programming language, restrict is a keyword, introduced by the C99 standard, that can be used in pointer declarations. By adding this type qualifier, a programmer hints to the compiler that for the lifetime of the pointer, no other pointer will be used to access the object to which it points.

What is char* restrict in C?

In C, restrict is a “type qualifier”. (Other things in this category are const and volatile ). This means, for some type T , we can write T restrict to get another type. For example, char const * restrict is a type. Actually, it only applies to pointer types, i.e. T * restrict .


1 Answers

The key on example 1 is that the lvalue *p that is used to access the underlying array pointed by r has its address based on r. Said differently, it is an indirect access through r. As *q also has its address based on s, all the accesses occur, even if indirectly, through the original restricted pointers: no UB here.

Example 2 is even more trivial. You declare a new restricted pointer based on the original one. So there is no UB either. But in example 2, both restricted qualifiers add exactly no value, because inside the block (the foo function definition) only one single pointer is used because aa is based on a.

In example 1, the restrict qualifiers declare to the compiler that the arrays pointed by r and s do not overlap: no access through r (directly or indirectly through p) should touch the array pointed to by s.

like image 191
Serge Ballesta Avatar answered Oct 13 '22 23:10

Serge Ballesta