为了账号安全,请及时绑定邮箱和手机立即绑定

gcc,严格混叠和恐怖故事

gcc,严格混叠和恐怖故事

C
繁花不似锦 2019-11-26 15:12:38
在gcc-strict-aliasing-and-casting-of-of-union中,我问是否有人遇到过通过指针进行联合修剪的问题。到目前为止,答案似乎是否定的。这个问题是广泛的:你有任何关于gcc和严格走样恐怖故事?背景:引用c99-strict-aliasing-rules-in-c-gcc中AndreyT的答案:“严格的别名规则植根于自[标准化]时代以来C和C ++中存在的标准部分。C89/ 90(6.3中存在禁止通过一种类型的左值访问一种类型的对象的子句。 )以及C ++ 98(3.10 / 15)。...并非所有编译器都希望(或胆敢)强制执行或依赖它。”好吧,海湾合作委员会现在敢于这样做,它的-fstrict-aliasing开关。这就造成了一些问题。参见,例如,关于Mysql错误的出色文章 http://davmac.wordpress.com/2009/10/,以及在http://cellperformance.beyond3d.com/articles/2006/06/understanding上同样出色的讨论-strict-aliasing.html。其他一些不相关的链接:Fno严格混叠的性能影响严格混叠什么时候可以对严格的指针别名进行安全处理如何在编译时检测严格的混叠重复一遍,您是否有自己的恐怖故事?当然,没有指出的问题-Wstrict-aliasing将是更可取的。也欢迎其他C编译器。新增6月2日:在第一个环节迈克尔·伯尔的答案,这也的确是有资格作为一个恐怖故事,也许是(2003年)有点过时。我做了一个快速测试,但是问题显然已经消失了。资源:#include <string.h>struct iw_event {               /* dummy! */    int len;};char *iwe_stream_add_event(    char *stream,               /* Stream of events */    char *ends,                 /* End of stream */    struct iw_event *iwe,       /* Payload */    int event_len)              /* Real size of payload */{    /* Check if it's possible */    if ((stream + event_len) < ends) {            iwe->len = event_len;            memcpy(stream, (char *) iwe, event_len);            stream += event_len;    }    return stream;}具体投诉是:一些用户抱怨说,如果在没有-fno-strict-aliasing的情况下编译[以上]代码,则写入和memcpy的顺序会颠倒(这意味着将假len复制到流中)。编译后的代码,在CYGWIN wih -O3上使用gcc 4.3.4(如果我输入错了,请更正我-我的汇编器有点生锈!):_iwe_stream_add_event:        pushl       %ebp        movl        %esp, %ebp        pushl       %ebx        subl        $20, %esp        movl        8(%ebp), %eax       # stream    --> %eax        movl        20(%ebp), %edx      # event_len --> %edx        leal        (%eax,%edx), %ebx   # sum       --> %ebx        cmpl        12(%ebp), %ebx      # compare sum with ends对于迈克尔回答中的第二个链接,*(unsigned short *)&a = 4;gcc通常会(总是?)发出警告。但我相信对此(对于gcc)的有效解决方案是使用:#define CAST(type, x) (((union {typeof(x) src; type dst;}*)&(x))->dst)// ...CAST(unsigned short, a) = 4;我问过在gcc-strict-aliasing-and-casting-a-union中这是否可以,但是到目前为止,没有人不同意。
查看完整描述

3 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

SWIG生成的代码依赖于严格的别名关闭,这可能会导致各种问题。


SWIGEXPORT jlong JNICALL Java_com_mylibJNI_make_1mystruct_1_1SWIG_12(

       JNIEnv *jenv, jclass jcls, jint jarg1, jint jarg2) {

  jlong jresult = 0 ;

  int arg1 ;

  int arg2 ;

  my_struct_t *result = 0 ;


  (void)jenv;

  (void)jcls;

  arg1 = (int)jarg1; 

  arg2 = (int)jarg2; 

  result = (my_struct_t *)make_my_struct(arg1,arg2);

  *(my_struct_t **)&jresult = result;              /* <<<< horror*/

  return jresult;

}


查看完整回答
反对 回复 2019-11-26
  • 3 回答
  • 0 关注
  • 525 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信