When using a bounding pointer in C, is it okay to change a variable using its original Identifier?

When using the restrict pointer in C, is it okay to change a variable using its initial Identifier ? For instance:

 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 creating restrict fooPtr .

Part 1 looks good to me. I got confused in Part 2 . And from what I understand about restrict , Part 3 is bad (the compiler allows it, but its behavior is undefined, and before the programmer does not).

+4
source share
4 answers

No, part 2 is not in order.

The specific part of the standard is 6.7.3.1/4. This section is rather dense and takes several readings, but P is a bounding pointer, and X is some object that it is accessing, and which is changing. So in your example P is fooPtr and X is foo . Then:

Each other value used to access the value of X also has its own address based on P.

"based" is defined in the previous paragraph and summarizes, lvalue foo does not have its address based on the restriction pointer P. Thus, the rule is violated when accessing the object foo through its own name.

Part 3 is not suitable for the same reason, the value lvalue *fooPtr2 also not based on P, but is also used to access X.

I say β€œout of order” - to be precise, the combination of 1 + 2 causes the behavior to be undefined, like the combination of 1 + 3. As long as you do not actually access the object using the restriction pointer, none of the definition of the restriction β€œkicks”. If you want you to be able to remove Part 1, keep an unused restriction pointer, then 2 and 3 will be fine.

+4
source

Yes, "part 3" is undefined behavior. From specification C99 (clause 6.7.3, clause 7):

An object that is accessed through a pointer with limited quality has a special association with this pointer. This association, defined in clause 6.7.3.1 below, requires that all references to this use of the object, directly or indirectly, value this specific pointer.

+1
source

I would say that No. 2 is bad. For example, the compiler can optimize loading a value in * fooPtr into a register, and then write that register value back to foo again later - after your ++ foo, so ++ foo will be lost.

+1
source

Assuming that all parts of your question are found in the same block, it is not normal to access the foo value directly (part 2) and not to access it using another pointer (part 3):

  • 6.7.3.1 Formal definition of a constraint

Each other lvalue used to access the value of X also has its own P-based address.

The formal definition of restrict quite difficult to implement (at least for me), however the following less formal description from standard amounts is also pretty good (at least for this case):

An object that is accessed using a restricted pointer has a special association with this pointer. This association, defined in clause 6.7.3.1 below, requires that all calls to this object directly or indirectly use the value of this particular pointer.

+1
source

All Articles