gpt4 book ai didi

c++ - 为什么编译器不再使用严格的别名来优化此UB

转载 作者:IT老高 更新时间:2023-10-28 22:19:52 25 4
gpt4 key购买 nike

本文是对Google进行严格别名的第一个结果是
http://dbp-consulting.com/tutorials/StrictAliasing.html
我注意到的一件有趣的事情是:http://goo.gl/lPtIa5

uint32_t swaphalves(uint32_t a) {
uint32_t acopy = a;
uint16_t* ptr = (uint16_t*)&acopy;
uint16_t tmp = ptr[0];
ptr[0] = ptr[1];
ptr[1] = tmp;
return acopy;
}

编译为
swaphalves(unsigned int):
mov eax, edi
ret

由GCC 4.4.7。任何比此新的编译器(在本文中提到了4.4,因此本文都没有错)不会像使用严格的别名那样实现该功能。
这是什么原因呢?
实际上是GCC中的bug还是GCC决定删除它,因为许多代码行都是以产生UB的方式编写的,或者仅仅是持续了多年的编译器回归...
而且Clang不会对其进行优化。

最佳答案

在这些情况下,GCC开发人员已尽力使编译器的行为“符合预期”。 (我希望可以为此提供适当的引用-我记得它有时会出现在邮件列表中)。

无论如何,您会说:

... does not implement the function as it could using strict aliasing



...可能意味着对严格的别名规则的用途有轻微的误解。您的代码示例将调用未定义的行为-因此,任何编译在技术上都是有效的,包括仅一个简单的 ret或陷阱指令的生成,甚至根本不包含任何代码(假定该方法永远不会被调用是合理的)。较新版本的GCC产生更长/更慢的代码几乎不是一个缺陷,因为产生完全执行任何特定操作的代码不会违反该标准。实际上,较新的版本通过产生代码来改善这种情况,这些代码可以执行程序员可能打算执行的代码,而不是无声地做一些不同的事情。

您想要的是-编译器生成的快速代码无法实现您想要的功能,还是慢一些的代码却无法实现您想要的功能?

话虽如此,我坚信您不应编写违反严格别名规则的代码。依靠编译器在“很明显”时做“正确”的事情是要走钢丝。优化已经足够困难,而编译器不必猜测程序员的意图并为此留出余地。此外,可以编写遵守规则的代码,并且编译器可以将其转换为非常有效的目标代码。确实,可以提出进一步的问题:

为什么早期版本的GCC会表现出与相同的方式,并依靠严格的别名规则来“优化”功能?

这有点复杂,但是对于本次讨论很有趣(尤其是根据有关编译器将花费一定长度来破坏代码的建议)。严格的混叠是称为“别名分析”的过程的组成部分(或更确切地说,是辅助规则的部分)。该过程确定两个指针是否别名。基本上,两个指针之间有3种可能的条件:
  • 它们一定不能混叠(严格的混叠规则可以轻松推断出这种情况,尽管有时可以用其他方式推论得出)。
  • 他们必须别名(这需要分析;例如,值传播可能会检测到这种情况)
  • 他们可能会别名。当其他两个条件都不能成立时,这是默认条件。

  • 对于您问题中的代码,严格的别名意味着 &acopyptr之间的“绝非别名”条件(进行此确定很简单,因为两个值具有不兼容的类型,不允许别名)。此条件允许您进行优化,然后您可以看到:可以丢弃 *ptr值的所有操作,因为它们在理论上不会影响 acopy的值,并且它们也不会以其他方式转义该函数(可以通过转义分析确定)。

    确定两个指针之间的“必须别名”条件需要花费更多的精力。此外,这样做时,编译器将需要(至少暂时地)忽略先前确定的“绝不别名”条件,这意味着它必须花费时间来尝试确定条件的真相,如果一切都应该如此,则必须假。

    当同时确定了MUST NOT ALIAS和MUST ALIAS条件时,我们就会遇到一种情况,即代码必须调用未定义的行为(并且我们可以发出警告)。然后,我们必须决定保留哪种条件以及丢弃哪种条件。因为在这种情况下,MUST NOT ALIAS来自用户可能(并且确实已经被)打破的约束,所以丢弃它是最好的选择。

    因此,较旧的GCC版本要么不做必要的分析来确定MUST ALIAS条件(也许是因为已经建立了相反的“MUST NOT ALIAS”条件),要么,较旧的GCC版本选择了在其中丢弃MUST ALIAS条件。优先选择“绝不假名”条件,这会导致更快的代码无法满足程序员最可能的意图。无论哪种情况,似乎新版本都会有所改进。

    关于c++ - 为什么编译器不再使用严格的别名来优化此UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34527729/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com