Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does dereferencing a char* inhibit strict aliasing optimizations?

Consider the following snippet as an example:

*pInt = 0xFFFF;
*pFloat = 5.0;

Since they are int and float pointers, the compiler will assume they don't alias and can exchange them for example.

Now let's assume we spice it up with this:

*pInt = 0xFFFF;
*pChar = 'X';
*pFloat = 5.0;

Since char* is allowed to alias anything, it may point to *pInt, so the assignment to *pInt cannot be moved beyond the assignment of *pChar, because it may legitimately point to *pInt and set its first byte to 'X'. Similarly pChar may point to *pFloat, assignment to *pFloat cannot be moved before the char assignment, because the code may intend to nullify the effects of the previous byte setting by reassigning the *pFloat .

Does this mean I can write and read through char* to create barriers for rearrangement and other strict aliasing related optimizations?

like image 226
Calmarius Avatar asked Sep 08 '17 12:09

Calmarius


People also ask

What is strict aliasing?

Strict aliasing is an assumption, made by the C (or C++) compiler, that dereferencing pointers to objects of different types will never refer to the same memory location (i.e. alias eachother.) Here are some basic examples of assumptions that may be made by the compiler when strict aliasing is enabled:

What is aliasing in C programming?

Aliasing: Aliasing refers to the situation where the same memory location can be accessed using different names. For Example, if a function takes two pointers A and B which have the same value, then the name A [0] aliases the name B [0] i.e., we say the pointers A and B alias each other. Below is the program to illustrate aliasing in C:

Is it possible to use restrict keyword without strict aliasing?

It is unlikely that code that does not enable strict aliasing would be able to take advantage of the restrict keyword. Using the restrict keyword allows a significant class of memory access optimizations critical to high performance code.

Why is memory referred to by SP an alias of Arg?

The memory referred to by sp is an alias of arg because they refer to the same address in memory. In C99, it is illegal to create an alias of a different type than the original. This is often refered to as the strict aliasing rule. The rule is enabled by default in GCC at optimization levels at or above O2.


1 Answers

Pointer aliasing mostly makes sense in scenarios when the compiler can't know if a pointer variable alias another pointer or not. As in the case when you compile a function located in a different translation unit than the caller.

void func (char* pChar, float* pFloat)
{
  *pChar = 'X';
  *pFloat = 5.0;
}

Here the pFloat assignment can indeed not be sequenced before the pChar one, because the compiler can't deduct that pChar does not point at the same location as pFloat.

However, when facing this scenario, the compiler can (and probably will) add a run-time check to see if the addresses could be pointing at overlapping memory or not. If they do, then the code must be sequenced in the given order. If not, then the code may be re-organized and optimized.

Meaning that you would only get memory barrier-like behavior in case the pointers actually do alias/point at overlapping memory. If not, then all bets regarding instruction ordering would be off. So this is probably not a mechanism that you should rely upon.

like image 64
Lundin Avatar answered Sep 18 '22 17:09

Lundin