int foo(void *restrict ptr1, void *restrict ptr2)
{
if (ptr1 == ptr2) {
return 1234;
} else {
return 4321;
}
}
restrict implies the the memory pointed to by a pointer is not aliased by any other pointer. Given that, then ptr1 and ptr2 cannot point to the same region, so the comparison is tautological and foo() should return 4321 in all cases.
Yet clang and gcc do not see it this way (https://godbolt.org/z/fvPd4a1vd). Is this a missed optimization or is there another reason?
According to the section 6.7.3 of the C99 Draft N1256:
Declaring a pointer as restrict ensures the compiler that no other pointer will modify the memory location pointed by the restricted pointer.
However, You can still have two restricted pointers pointing to the same memory region.
Again, the EXAMPLE 3 in 6.7.3.1 of the C99 Draft N1256 comes in handy:
This is the comment from the standard:
So, the answer to your question is: No, this is not a missed optimization by GCC or Clang.
As pointed out by Peter in the comments there could be a missing optimization based on the following undefined behavior related to restricted pointers:
Essentially, if two restricted pointers are not used to modify the data they are pointing to (which is the case of your function foo and the function h in my answer), no undefined behavior would occur even if they are pointing to the same memory region. Therefore, the compiler cannot say anything about their values at compilation time: they could be equal as well as different.
However, a different situation is the following:
Since both pointers are used to modify data they must be associated to different memory region otherwise an undefined behavior would occur (this is a consequence of the
restrictkeyword) and so an optimization could remove the subsequent comparison and return 1234 instead. However, both GCC and Clang don't perform such optimization as shown by Peter's comment.