Consider the following function:
int bar(const int* __restrict x, void g())
{
int result = *x;
g();
result += *x;
return result;
}
Do we need to read twice from x
because of the call to g()
? Or is the __restrict
ion enough to guarantee the invocation of g()
does not access/does not alter the value at address x
?
At this link we see the most popular compilers have to say about this (GodBolt; language standard C99, platform AMD64):
- clang 7.0: Restriction respected.
- GCC 8.3: No restriction.
- MSVC 19.16: No restriction.
Is clang rightly optimizing the second read away, or isn't it? I'm asking both for C and C++ here, as the behavior is the same (thanks @PSkocik).
Related information and some notes:
- Readers unfamiliar with
__restrict
(or__restrict__
) may want to have a look at: What does the restrict keyword mean in C++? - GCC's documentation page on restricted pointers in C++.
- I've opened a bug against GCC on this point.
- The fact that
x
is markedconst
is not significant here - we get the same behavior if we drop theconst
and the question stands as is.
I think this is effectively a C question, since C is effectively the language that has
restrict
, with a formal spec attached to it.The part of the C standard that governs the use of
restrict
is 6.7.3.1:The way I read it, the execution of
g()
falls under the execution of thebar
's block, sog()
is disallowed from modifying*x
andclang
is right to optimize out the second load (IOW, if*x
refers to a non-const global,g()
must not modify that global).