以下面的片段为例:
*pInt = 0xFFFF;
*pFloat = 5.0;
因为它们是 int
和 float
指针,编译器会假设它们没有别名并且可以交换它们。
现在让我们假设我们用这个来调味:
*pInt = 0xFFFF;
*pChar = 'X';
*pFloat = 5.0;
因为 char*
允许别名任何东西,它可能指向 *pInt
,所以对 *pInt
的赋值不能超出*pChar
的赋值,因为它可能合法地指向 *pInt
并将其第一个字节设置为“X”。
类似地,pChar
可能指向 *pFloat
,对 *pFloat
的赋值不能在 char 赋值之前移动,因为代码可能打算使效果无效通过重新分配 *pFloat
来调整先前的字节设置。
这是否意味着我可以写入和读取 char*
来为重新排列和其他严格的别名相关优化创建障碍?
最佳答案
指针别名在编译器不知道指针变量是否别名另一个指针的情况下最有意义。就像您编译位于与调用方不同的翻译单元中的函数时的情况。
void func (char* pChar, float* pFloat)
{
*pChar = 'X';
*pFloat = 5.0;
}
这里的pFloat
赋值确实不能排在pChar
之前,因为编译器无法推断pChar
不指向在与 pFloat
相同的位置。
但是,当遇到这种情况时,编译器可以(并且可能会)添加运行时检查以查看地址是否指向重叠内存。如果他们这样做,那么代码必须按照给定的顺序排序。如果不是,则可能会重新组织和优化代码。
这意味着如果指针实际上在重叠内存处执行别名/指向,您只会获得类似内存屏障的行为。如果不是,那么所有关于指令排序的赌注都将落空。所以这可能不是您应该依赖的机制。
关于c - 取消引用 char* 会抑制严格的别名优化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46116946/