There is no opposite of volatile
either. Basically the compiler assumes that a variable is not volatile unless you tell it any different.
Same goes for restrict
. Unless you tell a compiler that the only way to access a piece of memory is through that pointer, the compiler always must assume that other pointers exists that may point to the same memory location at runtime.
The difference is only that volatile
explicitly disables certain kind of optimizations that are naturally performed but could break code if the variable may change behind the back of the compiler noticing it (negative flag), whereas restrict
explicitly enables certain kind of optimization that a compile must not otherwise perform (positive flag).
But that's not directly related to strict aliasing. Strict aliasing means to strictly follow the C standard that says "Two pointer of different type pointing to the same memory location is undefined behavior". It's just the case that a C compiler can safely assume, that if two pointers have different type, they cannot alias each other and optimize accordingly, even if there is no restrict
keyword. It cannot say anything like that for two pointers of the same type and that's why restrict
exists. If you disable strict aliasing, the C compiler will allow this kind of undefined behavior and then the compiler must also treat two pointers of different kind as if they could alias each other, unless you use restrict
again.
Here are three examples:
void doStuff ( void * ptr1, void * ptr2 ) {
Can ptr1
and ptr2
both point to the same memory location? Yes, they can!
void doStuff ( void *restrict ptr3, void *restrict ptr4 ) {
Can ptr3
and ptr4
both point to the same memory location? No, they can't! They can't as that would violate what restrict
is telling the compiler here.
void doStuff ( int * ptr5, char * ptr6 ) {
Can ptr5
and ptr6
both point to the same memory location? Well, it depends. If strict aliasing is enforced, they can't, because they are of different type. If it is not enforced, they could, despite the C standard saying that this would be undefined behavior but most compilers will just allow it.
Now what would be the purpose of an "anti-restrict"? If strict aliasing is enabled and you would use the anti-restrict in the last sample, you'd break strict aliasing. And whether strict aliasing is enabled or not has no effect on the first two examples. So I fail to see the point of having an anti-restrict. Most of the time you cannot say for sure or know for sure if two pointers might alias each other, so using restrict
as a default behavior would break code en masse. It's only that in very rare situations you can guarantee that this is not the case and then you may use restrict
to let the compiler know about that, too.
restrict
is different. – Alexandriaalexandrian-fno-strict-aliasing
flag. I think that disabling global optimization is such a pity. – Adustrestrict
? – Selfoperating__may_alias__
attribute to solve the problem. – Armful#pragma
would do? Better than a language addition. – Selfoperatinguintptr_t
for that? – Knossos(uintptr_t)(void*)
instead. The problem appears around the list body and the two sentinel nodes which are declared of typestruct node*
rather thanvoid*
. – Adustunion
, then use the appropriate member of thatunion
at the appropriate time. See #99150 – Yet-fno-strict-aliasing
and get some performance enhancement. Thanks again. – Adust-fno-strict-aliasing
performance benefit of using therestrict
qualifier when possible (or cost of failing to use it) is increased, but if code usesrestrict
properly the-fno-strict-alising
dialect... – Bronson