【问题标题】:strict aliasing in CC中的严格别名
【发布时间】:2014-08-04 11:39:54
【问题描述】:

关于类型双关的问题:为什么这段代码违反了严格的别名规则:

int main()
{
    int a = 1;
    short j;

    printf("%i\n", j = *((short*)&a));
    return 0;
}

这不是:

int main()
{
    int a = 1;
    short j;
    int *p; 

    p=&a;
    printf("%i\n", j = *((short*)p));
    return 0;
}

gcc -fstrict-aliasing 构建。

谢谢!

【问题讨论】:

  • 因为a和j是指向同一个内存的不同类型?
  • 两者都有。编译器不保证会发出警告。尝试不同的混叠检测类型(-Wstrict-aliasing=n,其中 n 为 1、2 或 3)。

标签: c gcc strict-aliasing


【解决方案1】:

他们都违反了strict aliasing rule,我将引用我的answer here,上面写着(强调我的前进):

代码违反了strict aliasing rules,它通过不同类型的指针访问对象是非法的,尽管允许通过 char * 访问。允许编译器假设不同类型的指针不指向同一个内存并进行相应的优化。

gcc-Wstrict-aliasing=n here 的文档中有更详细的说明:

此选项仅在 -fstrict-aliasing 处于活动状态时才处于活动状态。它会警告可能破坏编译器用于优化的严格别名规则的代码。 级别越高,准确率越高(误报越少)。更高的级别也对应于更多的努力,类似于 -O 的工作方式。 -Wstrict-aliasing 等价于 -Wstrict-aliasing=3。

并将每个级别描述如下:

  • 1 级:最激进、最快速、最不准确。可能有用的时候 更高级别不会发出警告,但 -fstrict-aliasing 仍然会破坏代码, 因为它的假阴性很少。然而,它有许多虚假 积极的一面。警告所有可能之间的指针转换 不兼容的类型,即使从未取消引用。在前端运行 仅限。

  • 2 级:激进、快速、不太精确。可能还有很多假的 阳性(虽然没有 1 级那么多),而且很少有假阴性 (但可能超过 1 级)。与级别 1 不同,它仅在以下情况下发出警告 一个地址被占用。警告不完整的类型。跑在前面 仅结束。

  • Level 3(-Wstrict-aliasing 的默认值):应该很少有 false 阳性和少量假阴性。比 1 级或 2 级稍慢 启用优化时。 处理常见的双关语+取消引用 前端模式:*(int*)&some_float 如果优化是 启用,它也在后端运行,它处理多个 使用流敏感指向信息的语句案例。只警告 当转换后的指针被取消引用时。不警告 不完整的类型。

因此不能保证捕获所有实例,并且不同级别具有不同程度的准确度。

通常,您正在寻找的效果可以通过联合使用类型双关语来实现,我在上面的链接答案和 gcc explicitly supports 中对此进行了介绍。

【讨论】:

  • 谢谢!现在我明白了
猜你喜欢
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2011-02-15
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 2015-10-15
相关资源
最近更新 更多