If I have a member function declared like so:
double* restrict data(){
return m_data; // array member variable
}
can the restrict keyword do anything?
Apparently, with g++ (x86 architecture) it cannot, but are there other compilers/architectures where this type of construction makes sense, and would allow for optimized machine code generation?
I'm asking because the Blitz library (Blitz++) has a whole slew of functions declared in this manner, and it doesn't make sense that someone would go in and add the restrict keyword unless it actually does something. So before I go in and remove the restrict
's (to get rid of compiler warnings) I'd like to know how I'm abusing the code.
WHAT restrict
ARE WE TALKING ABOUT?
restrict
is, as it currently stands, non-standard.. which means that it's a compiler extension; it's non-portable in the sense that the C++ Standard doesn't mandate its existance, nor is there any formal text in it that tells us what it is supposed to do.
restrict
is currently compiler specific in C++, and one has to resort to the compiler documentation of their choice to see exactly what it is doing.
SOME THOUGHTS
There are many papers about the usage of restrict
, among them:
It's hinted at several places that the purpose of restrict
is to qualify pointers so that the compiler knows that two pointers in the same scope doesn't refer to the same memory location.
With this in mind we can easily see that the return-type has no potential collision with other pointers, so using it in such context will generally not gain any optimization opportunities. However; one must refer to the documented behaviour of the used implementation to know for sure.. as stated: restrict
is not standard, yet.
I also found the following thread where the developers of Blitz++ discusses the removal of strict
applied to the return-type of a function, since it doesn't do anything:
A LITTLE NOTE
As a further note, here's what the LLVM Documentation says about noalias
vs restrict
:
For function return values, C99’s restrict is not meaningful, while LLVM’s noalias is.