M
Me
Richard said:It gives the compiler no information whether it _does_ overlap, but it
does tell it that it may _assume_ there is no overlap, and hang the
consequences if the programmer bunged the job.
It only can make that assumption based on uses of the expressions. It
can't make it as is.
Not OK, and not OK, except for the quibble that your function body is
empty (and the declaration incomplete).
It is okay (minus my botched unnamed function parameters) otherwise you
have to deny that 6.7.3.1/10 is okay.
To quote the Standard:
# In what follows, a pointer expression E is said to be based on object
# P if (at some sequence point in the execution of B prior to the
# evaluation of E)
I don't see how this sentence is relevant.
Note: in the execution _of the block associated with the declaration_.
Not anywhere previously; in the block itself. You cannot use a
restricted pointer if it corresponds to another restricted pointer,
Yes you can. The meat and potatoes of restrict is 6.7.3.1/4. Nothing in
the first part of that paragraph applies with my example above, just
the second part.
_except_ in cases like this:
int * func(int * restrict ptr)
{
int * restrict ptr2 = ptr;
return ptr;
}
That's because the second restricted pointer was based on the first,
_inside_ the block which the restricted declaration belongs to.
Actually this example (which is exactly like 6.7.3.1/11) is the one
that's undefined. With 6.7.3.1/2, func is equivalent to:
int *arg = whatever, *ret;
{
int * restrict ptr = arg;
int * restrict ptr2 = ptr;
ret = ptr;
}
With 6.7.3.1/4:
- ptr is P2 associated with block B2
- ptr2 is P associated with block B
And neither the requirements of B and B2 is met in the rest of
6.7.3.1/4. To make this defined, you have to lose at least 1 restrict
qualifier.
Even though http://www.lysator.liu.se/c/restrict.html is slightly
outdated (the two main ways are that the current standard has extra
magic associated with restricted pointers to const T and also it has
better wording when dealing with lvalues and the object it accesses),
the examples are very good. The specific section you should look at is
3.8. Notice how the assignment goes from a restricted pointer to a
regular pointer. The whole reason there are fancy pants semantics in
the standard dealing with assignments is so a compiler can track how a
restricted pointer P can propigate to regular pointer expressions. This
is extremely important in C because you lose the restrict qualifier by
doing &*p or something similar (3.6 on lysator has further trivial but
common examples).