【发布时间】:2014-07-21 16:01:24
【问题描述】:
我在过去一周左右一直在阅读严格的别名规则并看到这篇文章:Understanding C/C++ Strict Aliasing。
本文介绍了两种交换 32 位整数的一半的方法,给出了很好的示例和违反严格别名规则的示例。不过,我无法理解其中一个示例。
此代码被描述为已损坏。
uint32_t
swaphalves(uint32_t a)
{
a = (a >> 16) | (a << 16);
return a;
}
给出的原因是:
这个版本看起来合理,但你不知道左右两边 |每个人都将获得
a的原始版本,或者如果其中一个人将获得以下结果 另一个。这里没有顺序点,所以我们对顺序一无所知 这里的操作,你可能会从同一个编译器使用不同的编译器得到不同的结果 优化级别。
我不同意。这段代码对我来说很好。在a = (a >> 16 | (a << 16); 行中只有一次对a 的写入,我希望a 的两次读取都发生在该写入之前。此外,没有指针或引用,也没有不兼容的类型。
我是否在此代码中遗漏了严格的别名违规,或者文章不正确?
【问题讨论】:
-
这是在单线程场景中吗?
-
这是我的假设,虽然我认为文章中没有明确说明。
-
@ParkYoung-Bae 如果没有,它会因为与严格的混叠和序列点完全无关的原因而损坏,并且仅在右侧读取一次无法修复它。
-
这个例子显然是不正确的。如果这种情况是正确的,那么您根本无法编码。我的意思是,同样的论点
a = a + a也不应该起作用。总而言之:永远不要相信这家咨询公司。 -
我在answer 中引用的严格别名文章是更好的来源。
标签: c++ c strict-aliasing