用C严格别名 [英] strict aliasing in C

查看:143
本文介绍了用C严格别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

约型双关语问:为什么这code打破严格走样规则:

Question about type punning: why does this code break strict aliasing rules:

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走样建立

感谢您!

推荐答案

他们都违反了的严格别名规则,我要引用我的 这里回答它说(重点煤矿前进的):

They both violate the strict aliasing rule, I am going to quote my answer here which says (emphasis mine going forward):

code违反href=\"http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html\" rel=\"nofollow\">严格别名规则是非法的,通过不同类型的指针访问对象,虽然通过一个char *允许访问。编译器被允许假设不同类型的指针没有指向相同的内存和相应的优化。

code violates the strict aliasing rules which makes it illegal to access an object through a pointer of a different type, although access through a char * is allowed. The compiler is allowed to assume that pointers of different types do not point to the same memory and optimize accordingly.

GCC -Wstrict走样= N 这里它说:

这个选项时-fstrict走样激活才有效。报告警告说,大约code可能打破编译器使用优化严格别名规则。 较高水平对应于更高的精度(减少误判)。更高的水平也相应付出更大的努力,类似-O的工作方式。 -Wstrict走样相当于-Wstrict走样= 3。

This option is only active when -fstrict-aliasing is active. It warns about code that might break the strict aliasing rules that the compiler is using for optimization. Higher levels correspond to higher accuracy (fewer false positives). Higher levels also correspond to more effort, similar to the way -O works. -Wstrict-aliasing is equivalent to -Wstrict-aliasing=3.

和描述了每个级别如下:

and describes each level as follows:


      
  • 1级:最积极的,快速的,不准确的。可能有用当
      更高水平的不发出警告,但-fstrict走样仍然打破了code,
      因为它有极少数的假阴性。然而,它有很多假
      阳性。为警告可能之间的所有指针转换
      不兼容的类型,即使从来没有取消引用。在前端的运行
      只有

  • Level 1: Most aggressive, quick, least accurate. Possibly useful when higher levels do not warn but -fstrict-aliasing still breaks the code, as it has very few false negatives. However, it has many false positives. Warns for all pointer conversions between possibly incompatible types, even if never dereferenced. Runs in the front end only.

2级:积极,快速,不要太precise。可还是有很多假的
  正片(不多达虽然1级),很少假阴性
  (但可能超过1级)。不同于1级,它只时发出警告
  一个地址取。发出警告不完全类型。运行在前面
  结束而已。

Level 2: Aggressive, quick, not too precise. May still have many false positives (not as many as level 1 though), and few false negatives (but possibly more than level 1). Unlike level 1, it only warns when an address is taken. Warns about incomplete types. Runs in the front end only.

3级(默认-Wstrict走样):应该有很少的假
  正和几个假阴性。稍显不足的水平1或2慢
  当已启用优化。 负责普通双关语+非关联化
  模式在前端: *为(int *)及some_float
如果优化
  启用,它也运行在后端,在那里它与多个涉及
  声明的情况下使用流量敏感的指向信息。只有警告
  当转换后的指针被废弃。不警告
  不完全类型。

Level 3 (default for -Wstrict-aliasing): Should have very few false positives and few false negatives. Slightly slower than levels 1 or 2 when optimization is enabled. Takes care of the common pun+dereference pattern in the front end: *(int*)&some_float. If optimization is enabled, it also runs in the back end, where it deals with multiple statement cases using flow-sensitive points-to information. Only warns when the converted pointer is dereferenced. Does not warn about incomplete types.

所以,它不能保证捕获所有实例和不同的级别会有不同的精确度。

So it is not guaranteed to catch all instances and different levels have different degrees of accuracy.

通常,您正在寻找可通过工会使用双关类型来实现,我在我上面​​的链接的答案覆盖效果,的 GCC明确支持

Typically the effect you are looking for can be accomplished using type punning through a union, which I cover in my linked answer above and gcc explicitly supports.

这篇关于用C严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆