views:

59

answers:

4

When using a restrict Pointer in C, is it OK to change the variable using its initial Identifier? For example:

int foo = 0;

int * restrict fooPtr = &foo;
++(*fooPtr);                   // Part 1: foo is 1 (OK)

++foo;                         // Part 2: foo is 2 (Is this OK?)

int * fooPtr2 = &foo;
++(*fooPtr2);                  // Part 3: foo is 3 (BAD: You shouldn't access via a second pointer)

...I changed the value of foo through foo after the restrict fooPtr was created.

Part 1 looks OK to me. I'm confused about Part 2. And from what I understand about restrict, Part 3 is bad (compiler allows it, but its behavior is undefined, and it's up to the programmer not to do that).

+1  A: 

Yes, "part 3" is undefined behaviour. From the C99 spec (6.7.3, paragraph 7):

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.

Oli Charlesworth
Awesome. How about "Part 2"? The way I interpret that is: "Never access the variable pointed to by a restrict Pointer by any other means, except for that restrict Pointer". That would mean "Part 2" in my example would be bad, if my interpretation is correct.
Dave Gallagher
+2  A: 

No, Part 2 is not OK.

The specific part of the standard is 6.7.3.1/4. This section is pretty dense, and takes a few re-reads, but P is a restrict pointer, and X is some object it is used to access, and which is modified. So in your example P is fooPtr and X is foo. Then:

Every other lvalue used to access the value of X shall also have its address based on P.

"based on" is defined in the previous paragraph, and to summarize, the lvalue foo does not have its address based on the restrict pointer P. So the rule is broken when you access the object foo through its own name.

Part 3 is not OK for exactly the same reason, the lvalue *fooPtr2 isn't based on P either, but is also used to access X.

I say "not OK" - to be precise, the combination of 1+2 provokes undefined behavior, as does the combination of 1+3. As long as you don't actually access the object through the restrict pointer, none of the definition of restrict "kicks in". If you wanted to you could remove Part 1, retain the unused restrict pointer, and then 2 and 3 would be OK.

Steve Jessop
Thanks a lot Steve! :)
Dave Gallagher
Do you mean that if we want to access the X object via it's own name and pointer we may have bug?
Green Code
Also how is this optimization done?
Green Code
@Green Code, this appears to have a good overview of how restrict optimization is done: http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html
Dave Gallagher
@Green Code: "we may have bug". Yes. If you access the object via its own name, during the lifetime the restrict pointer, then you may have a bug. If the program can't live with that, it shouldn't take a restrict pointer to the object.
Steve Jessop
+1  A: 

I'd say #2 is bad. For instance, the compiler might optimize by loading the value at *fooPtr into a register, and then write that register value back out to foo again later - after your ++foo, so that the ++foo is lost.

Bzzt
Thanks so much!
Dave Gallagher
+1  A: 

Assuming that all of the parts of your question occur in the same block, it's not OK to access the value of foo directly (part 2) nor to access it via another pointer (part 3):

  • 6.7.3.1 Formal definition of restrict

Every other lvalue used to access the value of X shall also have its address based on P.

The formal definition of restrict is quite difficult to follow (at least it is for me), however the following less formal description also from the standard sums it up pretty well (at least for this case):

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.

Michael Burr
Thanks Michael! Very helpful!
Dave Gallagher