Search code examples
c++pass-by-referencerestrict-qualifier

Why is the __restrict__ modifier not enforced?


If a function parameter is annotated const int &x and I try to do x++ in the function body, I get a compile time error for modifying a read-only reference. But if I use the __restrict__ modifier like so:

void foo(int & __restrict__ a, int & __restrict__ b) {
    if (a == 1)
        b = 2;
    if (a == 2)
        b = 3;
}

int main() {
    int x = 1;
    foo(x, x); // should be illegal?
    cout << x;
}

...I do not get a compile time error. If I run this code unoptimized the output is 3, but if I run it with -O1 or higher the output is 2. It seems like detecting x to be passed twice would be straightforward and easy to disallow. Why does C++ protect against bad use of const but not bad use of __restrict__?


Solution

  • You are looking at __restrict__ backwards.

    __restrict__ is an implementation extension that the programmer can use to signal intent, to maximise generated code quality and performance ("optimisations").

    It is not a check, or an added constraint on the program.

    It is not part of the type system, so it's not part of the function's type, so it cannot be enforced at callsites (in general).

    It is like some other extensions (such as __builtin_unreachable), that you use to tell the compiler something.

    In this case, you're telling it "I am not referring to the pointee via any other pointer".

    You're not asking it "please stop me from referring to the pointee via any other pointer".

    C and C++ compilers already perform strong "aliasing" checks where they can. The __restrict__ keyword is a way for you to tell it "I am sure about this", in cases where the automatic aliasing detection cannot work (due to, for example, translation unit boundaries). Because the automatic aliasing detection cannot work, __restrict__ cannot be enforced.

    And, even if it could be, that would be the opposite of the purpose of the modifier.