当前位置:  技术问答>linux和unix

提领类型双关的指针将破坏强重叠规则 wxwidget

    来源: 互联网  发布时间:2016-03-31

    本文导语:  在编译wxwidegt程序的时候,出现了这个警告。不知是什么原因?谢谢帮助! /usr/include/wx-2.8/wx/hashmap.h||In member function ‘wxLongToLongHashMap_wxImplementation_HashTable::Node** wxLongToLongHashMap_wxImplementation_HashTable::GetNodePtr(const long...

在编译wxwidegt程序的时候,出现了这个警告。不知是什么原因?谢谢帮助!

/usr/include/wx-2.8/wx/hashmap.h||In member function ‘wxLongToLongHashMap_wxImplementation_HashTable::Node** wxLongToLongHashMap_wxImplementation_HashTable::GetNodePtr(const long int&) const’:|
/usr/include/wx-2.8/wx/hashmap.h|714|警告: 提领类型双关的指针将破坏强重叠规则|
/usr/include/wx-2.8/wx/clntdata.h||In member function ‘wxShadowObjectMethods_wxImplementation_HashTable::Node** wxShadowObjectMethods_wxImplementation_HashTable::GetNodePtr(const wxString&) const’:|
/usr/include/wx-2.8/wx/clntdata.h|20|警告: 提领类型双关的指针将破坏强重叠规则|
/usr/include/wx-2.8/wx/clntdata.h||In member function ‘wxShadowObjectFields_wxImplementation_HashTable::Node** wxShadowObjectFields_wxImplementation_HashTable::GetNodePtr(const wxString&) const’:|
/usr/include/wx-2.8/wx/clntdata.h|25|警告: 提领类型双关的指针将破坏强重叠规则|
/usr/include/wx-2.8/wx/gdicmn.h||In member function ‘wxStringToColourHashMap_wxImplementation_HashTable::Node** wxStringToColourHashMap_wxImplementation_HashTable::GetNodePtr(const wxString&) const’:|
/usr/include/wx-2.8/wx/gdicmn.h|544|警告: 提领类型双关的指针将破坏强重叠规则|
/usr/include/wx-2.8/wx/image.h||In member function ‘wxImageHistogramBase_wxImplementation_HashTable::Node** wxImageHistogramBase_wxImplementation_HashTable::GetNodePtr(const long unsigned int&) const’:|
/usr/include/wx-2.8/wx/image.h|136|警告: 提领类型双关的指针将破坏强重叠规则|
||=== Build finished: 5 errors, 0 warnings ===|

|

此Warning的英文输出是:
warning: dereferencing type-punned pointer will break strict-aliasing rules

下面的文章详细的说明了出现此warning的情况,很有用(http://www.zeali.net/entry/454):

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.

  简而言之, 在该参数激活的情况下,编译器希望不同类型的对象不会指向同一个地址。比如像这段代码:

int retLen;
someSetFunc((unsigned long*)&retLen);
printf("ret len = %dn",retLen);

  由于 someSetFunc 的传入参数类型定义为 unsigned long ,所以需要进行这样的指针类型强制 cast 。但对于 -fstrict-aliasing 优化参数来说,这样的转换是有潜在问题的(但实际上可能并不会造成任何问题)。所以如果现有的源代码存在太多这样的类型强制转换的问题的话,对这些代码进行修改也许会是场噩梦。最简单的方法是使用 -fno-strict-aliasing 参数来关闭 gcc 的优化选项,代价是放弃了 strict-aliasing 编译优化可能带来的可执行代码的性能提升。当然也可以用 -Wno-strict-aliasing 来屏蔽相关的 warning 信息,但无论这些 warning 信息多么的无关紧要,总还是“疑似危险”,所以可能的话最好还是把所有的 warning 都消灭掉。

  消灭的方法也不算复杂,正如 gcc manual 所示的那样,可以是采用 union 的不同成员变量来完成类型的转换。上面那段代码可以改为:

union u_retLen
{
int retLen;
unsigned long ptr;
};
someSetFunc(&u_retLen.ptr);
printf("ret len = %dn",u_retLen.retLen);

  虽然会使源代码变得丑陋,但对于大部分已有的源代码来说,这可能是改动最小的方案了。而对于新写的代码来说,如何更好的设计函数的入口参数(比如使用 void*)可能才是需要去思考的问题了。


|
在make之前加LANG=C,看看输出的英文信息。

|
这个strict-aliasing确实很恶心。 你说要是加上这个检查, 用 C 还有什么意义?

    
 
 

您可能感兴趣的文章:

  • Linux提示提领指向不完全指针
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3