【发布时间】:2019-05-26 06:54:36
【问题描述】:
我目前想知道严格别名规则背后的基本原理。我知道在 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;
}
我可能错了,但据我所知,编译器应该能够完美而轻松地追踪类型转换并避免对显式转换的类型进行优化(就像它避免对相同类型的指针进行此类优化一样) 在使用受影响的值调用的任何内容上。
那么,我错过了哪些严格别名规则的问题,编译器无法轻松解决以自动检测可能的优化)?
【问题讨论】:
-
您是否查看过关于严格别名的规范问答及其含义。原因基本上是“因为它允许更强大的优化”;这是通常的原因。与有符号整数溢出相同。
-
@JonathanLeffler 是的,我想是的,我想的不是没有优化的编译器,而是一个检测何时无法进行这种优化的编译器。
-
您对非 x86 系统有任何经验吗?对不同数据类型有严格对齐限制的那些,例如
double或long必须在8 字节边界上,以免您的进程被SIGBUS之类的东西杀死?从技术上讲,这不是一个严格的混叠问题,但它涉及到许多相同的潜在问题。 -
uint64_t几乎按照定义与uint32_t@AndrewHenle 对齐,所以这里肯定不是问题。 -
标记的行不是严格的别名违规。违规行为在下一行。
标签: c language-lawyer c11 strict-aliasing