取消引用char*会禁止严格的别名优化吗?

Cal*_*ius 15 c strict-aliasing

以下面的代码片段为例:

*pInt = 0xFFFF;
*pFloat = 5.0;
Run Code Online (Sandbox Code Playgroud)

由于他们是intfloat指针,编译器将假定他们不这样做别名,例如可以交换.

现在让我们假设我们用这个来加强它:

*pInt = 0xFFFF;
*pChar = 'X';
*pFloat = 5.0;
Run Code Online (Sandbox Code Playgroud)

因为char*允许别名,它可能指向*pInt,所以赋值*pInt不能超出赋值*pChar,因为它可以合法地指向*pInt并将其第一个字节设置为'X'.类似地pChar可以指向*pFloat,*pFloat在char赋值之前不能移动赋值,因为代码可能打算通过重新分配来取消先前字节设置的效果*pFloat.

这是否意味着我可以通过编写和读取char*来为重新排列和其他严格的别名相关优化创建障碍?

Lun*_*din 5

在编译器无法知道指针变量是否为另一个指针的别名时,指针别名通常很有意义.与编译位于与调用者不同的翻译单元中的函数的情况一样.

void func (char* pChar, float* pFloat)
{
  *pChar = 'X';
  *pFloat = 5.0;
}
Run Code Online (Sandbox Code Playgroud)

这里的pFloat分配确实不能在分配之前排序pChar,因为编译器不能扣除pChar不指向同一位置的分配pFloat.

但是,在面对这种情况时,编译器可以(并且可能会)添加运行时检查以查看地址是否指向重叠内存.如果他们这样做,那么代码必须按给定的顺序排序.如果不是,则可以重新组织和优化代码.

这意味着只有在指针实际上为别名/指向重叠内存的情况下才会获得类似内存屏障的行为.如果没有,那么关于指令排序的所有赌注都将被取消.所以这可能不是你应该依赖的机制.