免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1033 | 回复: 0
打印 上一主题 下一主题

GCC warnings about strict-aliasing [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-10-12 13:21 |只看该作者 |倒序浏览
转载请保留本行原始链接信息 :
http://www.zeali.net/entry/454
MADE 1n ZEAL
                               
                               
                               
                               
warning: dereferencing type-punned pointer will break strict-aliasing rules
  
  在 gcc 2.x 下编译没有任何 warning 信息的代码换到 gcc 3.x 版本下之后出现了类似的 warning 。原因是 gcc 3 引入了 strict aliasing 架构,当编译时使用了 -fstrict-aliasing 参数(该参数在使用了 -O2 , -O3, -Os 优化参数的情况下默认生效),而源代码中存在一些违反了 strict-aliasing 规则的地方的话,编译器就会对这部分代码提出 warning 。
  
  gcc 3 manual 对于 -fstrict-aliasing 参数的说明是:Allows
the compiler to assume the strictest aliasing rules applicable to the
language being compiled.  For C (and C++), this activates optimizations
based on the type of expressions.  In particular, an object of one type
is assumed never to reside at the same address as an object of a
different type, unless the types are almost the same.  For example, an
"unsigned int" can alias an "int", but not a "void*" or a "double".  A
character type may alias any other type.
  
  简而言之, 在该参数激活的情况下,编译器希望不同类型的对象不会指向同一个地址。比如像这段代码:
  
[color="#0000ff"]int retLen;
someSetFunc(([color="#0000ff"]unsigned long*)&retLen);
[color="#ff0000"]printf([color="#ff1493"]"ret len = %d\n",retLen);
  
  由于 someSetFunc 的传入参数类型定义为 [color="#0000ff"]unsigned long ,所以需要进行这样的指针类型强制 cast 。但对于 -fstrict-aliasing 优化参数来说,这样的转换是有潜在问题的(但实际上可能并不会造成任何问题)。所以如果现有的源代码存在太多这样的类型强制转换的问题的话,对这些代码进行修改也许会是场噩梦。最简单的方法是使用 -fno-strict-aliasing 参数来关闭 gcc 的优化选项,代价是放弃了 strict-aliasing 编译优化可能带来的可执行代码的性能提升。当然也可以用 -Wno-strict-aliasing 来屏蔽相关的 warning 信息,但无论这些 warning 信息多么的无关紧要,总还是“疑似危险”,所以可能的话最好还是把所有的 warning 都消灭掉。
  
  消灭的方法也不算复杂,正如 gcc manual 所示的那样,可以是采用 union 的不同成员变量来完成类型的转换。上面那段代码可以改为:
  
[color="#0000ff"]union u_retLen
{
[color="#0000ff"]int retLen;
[color="#0000ff"]unsigned long ptr;
};
someSetFunc(&u_retLen.ptr);
[color="#ff0000"]printf([color="#ff1493"]"ret len = %d\n",u_retLen.retLen);
  
  虽然会使源代码变得丑陋,但对于大部分已有的源代码来说,这可能是改动最小的方案了。而对于新写的代码来说,如何更好的设计函数的入口参数(比如使用 void*)可能才是需要去思考的问题了。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/4329/showart_2068246.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP