c 你什么时候不想使用严格的别名?

标签 c gcc strict-aliasing

我最近了解了 C 中的严格别名并阅读了这篇文章

What is the strict aliasing rule?

但我对什么时候不想启用严格别名感到困惑。我使用 GCC 开发嵌入式 C 应用程序,我发现许多项目已将 -fno-strict-aliasing 添加到发布版本的额外标志中,但我不明白为什么他们不会不想为性能启用严格别名。有没有人有一个很好的例子/情况,你不想在 C 中使用严格的别名?

此外,如果我们违反严格别名规则但告诉编译器不要进行任何严格别名优化,这是否意味着它不是未定义的行为?

谢谢

最佳答案

... when one would not want to enable strict aliasing

严格的别名是 C 标准设定的一项要求(或者更确切地说是多项要求)。因此,符合标准的 C 代码必须遵守标准设置的(严格的)别名规则。

编译器可以使用这些规则来优化生成的代码。如果某些 C 代码违反了标准别名规则,编译器可能会由于优化而生成行为异常的代码。大多数编译器都可以选择关闭基于别名规则的优化。

所以答案是:如果你的代码违反了“严格的别名”规则,你可以告诉编译器不要根据别名规则进行优化。

这引出了一个新问题:为什么要编写违反别名规则的代码?

一个原因可能是性能。换句话说 - 如果您确切地知道您的系统在发生违规情况下的行为方式并且您的代码通过违反该违规行为表现得更好,您可能想说:我更喜欢性能高于标准合规性。

我看到提到的一个例子是(网络)数据包校验和的计算。例如,保存数据包的结构可能包含许多不同的字段,如 mac、ip 等。但要计算某种校验和,您可能希望将数据包视为整数数组。使用 uint32_t * p = &packet 这样的代码很容易做到这一点。它违反了别名规则,但可以在目标系统上正常工作,因为编译器不根据严格的别名规则进行优化。

另一个原因可能是代码的可读性。为了避免违反别名规则,您通常需要编写“一些额外的代码”,例如将事物放在 union 中,进行位移和逻辑或计算 int 值等。有些人发现此类代码的可读性和可维护性较差,因此他们更愿意通过违反别名规则来“编写更简单的代码”(因此在编译器中将其关闭)。

关于c 你什么时候不想使用严格的别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63796726/

相关文章:

c - Clang 是否误解了 'const' 指针说明符?

c - C中 "restrict"的相反关键字?

c++ - 使用指针转换来存储/转换值 : Am I breaking the strict aliasing rule?

c - 如何区分两个未初始化的静态变量

将字符串从一个结构复制到另一个结构

c - 使用 gcc 编译时 -ffreestanding 和 -nostdlib 之间的区别

c - Intel x86 SSE SIMD 指令入门

c++ - 为什么可以比较最后一个元素?

java - 用c写一个关键的监听器

c - : :"r" vs :"=r" assembly clarification