gpt4 book ai didi

c - 严格的别名规则背后的基本原理是什么?

转载 作者:太空狗 更新时间:2023-10-29 14:50:14 25 4
gpt4 key购买 nike

我目前想知道严格别名规则背后的基本原理。我知道 C 中不允许使用某些别名,其目的是允许优化,但令我惊讶的是,在定义标准时,这是优于跟踪类型转换的首选解决方案。

因此,显然以下示例违反了严格的别名规则:

uint64_t swap(uint64_t val)
{
uint64_t copy = val;
uint32_t *ptr = (uint32_t*)© // strict aliasing violation
uint32_t tmp = ptr[0];
ptr[0] = ptr[1];
ptr[1] = tmp;
return copy;
}

我可能是错的,但据我所知,编译器应该能够完美而简单地追踪类型转换并避免对显式转换的类型进行优化(就像它避免对相同类型的指针进行此类优化一样) 在任何使用受影响的值调用的对象上。

那么,我错过了哪些编译器无法轻松解决以自动检测可能的优化的严格别名规则问题?

最佳答案

由于在此示例中所有代码对编译器都是可见的,因此假设编译器可以确定请求的内容并生成所需的汇编代码。但是,证明一种理论上不需要严格别名规则的情况并不能证明没有其他情况需要它。

考虑代码是否包含:

foo(&val, ptr)

其中 foo 的声明是 void foo(uint64_t *a, uint32_t *b);。然后,在可能位于另一个翻译单元中的 foo 内部,编译器将无法知道 ab 指向(部分的)相同的对象。

然后有两个选择:一,语言可能允许别名,在这种情况下,编译器在翻译 foo 时,不能依赖于 *a*b 是不同的。例如,无论何时向*b 写入内容,编译器都必须生成汇编代码以重新加载*a,因为它可能已更改。不允许进行优化,例如在使用 *a 时在寄存器中保留副本。

第二个选择,两个,是禁止别名(具体来说,如果程序这样做,则不定义行为)。在这种情况下,编译器可以根据 *a*b 不同的事实进行优化。

C 委员会选择了选项二,因为它提供了更好的性能,同时又不会过度限制程序员。

关于c - 严格的别名规则背后的基本原理是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53958680/

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