gcc,严格混叠和恐怖故事

在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中这是否可以,但是到目前为止,没有人不同意。


繁花不似锦
浏览 526回答 3
3回答

喵喵时光机

SWIG生成的代码依赖于严格的别名关闭,这可能会导致各种问题。SWIGEXPORT jlong JNICALL Java_com_mylibJNI_make_1mystruct_1_1SWIG_12(&nbsp; &nbsp; &nbsp; &nbsp;JNIEnv *jenv, jclass jcls, jint jarg1, jint jarg2) {&nbsp; jlong jresult = 0 ;&nbsp; int arg1 ;&nbsp; int arg2 ;&nbsp; my_struct_t *result = 0 ;&nbsp; (void)jenv;&nbsp; (void)jcls;&nbsp; arg1 = (int)jarg1;&nbsp;&nbsp; arg2 = (int)jarg2;&nbsp;&nbsp; result = (my_struct_t *)make_my_struct(arg1,arg2);&nbsp; *(my_struct_t **)&jresult = result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* <<<< horror*/&nbsp; return jresult;}
打开App,查看更多内容
随时随地看视频慕课网APP