6

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';
    }
}
roschach
  • 8,390
  • 14
  • 74
  • 124
user2711115
  • 457
  • 3
  • 18
  • 2
    Your code never dereferences any pointers? – Kerrek SB Mar 14 '17 at 09:02
  • The point was to know whether the assignment aa = a was undefined behavior by the above definition, but I have edited it – user2711115 Mar 14 '17 at 09:06
  • [check answer 2](http://stackoverflow.com/questions/745870/realistic-usage-of-the-c99-restrict-keyword) – jjm Mar 14 '17 at 09:22
  • [How to use restrict](http://web.archive.org/web/20120225055041/http://developers.sun.com/solaris/articles/cc_restrict.html) – jjm Mar 14 '17 at 09:31
  • A `for` loop is nominally a block around a `while` loop, so that should be OK. – Kerrek SB Mar 14 '17 at 09:46
  • `restrict` is merely a contract between the programmer and the compiler. Upon encountering `restrict` qualified pointers as parameters to a function, the programmer has to promise the compiler that they won't give that function two parameters that overlap in memory. If the compiler can assume this, it won't have to include additional overhead code to handle overlaps. But there is nothing forcing the compiler to give a diagnostic if the programmer violates this contract. This is how it goes when you have too many compiler people present in the C standard committee... – Lundin Mar 14 '17 at 12:49

1 Answers1

2

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.

roschach
  • 8,390
  • 14
  • 74
  • 124
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thanks, I had a somewhat vague idea of what direct/indirect access meant and that cleared it up nicely! – user2711115 Mar 14 '17 at 10:08
  • As I read more about this, I came across this article (specifically targetting the TI) http://processors.wiki.ti.com/images/f/ff/Bartley%3DWiki_1.1%3DPerformance_Tuning_with_the_RESTRICT_Keyword.pdf If you look at section 3.5 on page 18, it clearly contradicts cppreference and what you just said about exemple 1. Am I correct to assume the TI compiler does not follow the standard there? – user2711115 Mar 14 '17 at 10:43