严格的指针别名:是否通过“挥发性”指针/参考解决方案访问?
-
24-10-2019 - |
题
紧跟 一个特定的问题, ,一个自我提示和对此发表评论,我想了解这是一个适当的解决方案,解决方法/黑客或完全错误的解决方案。
具体来说,我重写了代码:
T x = ...;
if (*reinterpret_cast <int*> (&x) == 0)
...
作为:
T x = ...;
if (*reinterpret_cast <volatile int*> (&x) == 0)
...
与 volatile
指针的预选赛。
让我们假设治疗 T
作为 int
在我的情况下是有道理的。这是否通过 volatile
参考解决指针混叠问题?
为了参考,从规范中:
注意:挥发性是实施的暗示,以避免涉及对象的积极优化,因为可以通过实现的方式来更改对象的值。有关详细语义,请参见1.9。通常,挥发性的语义旨在在C ++中相同。
编辑:
上面的代码确实至少在GCC 4.5上解决了我的问题。
解决方案
挥发性无法帮助您在这里避免不确定的行为。因此,如果它对您有用GCC有效,那就是运气。
假设t是一个豆荚。然后,正确的方法是
T x = …;
int i;
memcpy(&i,&x,sizeof i);
if (i==0)
…
那里!没有严格的混叠问题,也没有记忆对准问题。 GCC甚至将memcpy作为固有函数处理(在这种情况下无函数调用)。
其他提示
挥发性无法帮助您在这里避免不确定的行为。
好吧,关于 volatile
在标准中不清楚。我主要同意您的回答,但是现在我想稍微不同意。
为了了解什么 volatile
意思是,对于大多数人来说,标准尚不清楚,尤其是一些编译器作家。最好思考:使用时 volatile
(并且仅在当时),C/C ++几乎是高级组件.
写信给 volatile
如果不够volatile
并不暗示原子)。
写信给 volatile
LVALUE,编译器将发出负载或多重负载,如果不够。
当然,在没有明确的负载或存储的情况下,编译器将发布指令,暗示负载或存储。
Sellibitze提供了最好的解决方案: 利用 memcpy
对于位重新解释。
但是,如果所有进入内存区域的访问均已完成 volatile
lvalues, 很明显,严格的别名规则不适用. 。这是您问题的答案。