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

StackOverflow https://stackoverflow.com/questions/3936060

  •  30-09-2019
  •  | 
  •  

문제

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).

도움이 되었습니까?

해결책

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.

다른 팁

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.

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.

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top