gcc, strict-aliasing und Horrorgeschichten

In gcc-strict-aliasing-und-casting-über-eine-union ich fragte, ob noch jemand Probleme mit union Zweideutigkeiten über Zeiger. Bisher scheint die Antwort zu sein Keine.

Diese Frage ist breiter: Sie haben alle horror-Geschichten über gcc und strict-aliasing?

Hintergrund: Zitat aus AndreyT Antwort im c99-strict-aliasing-Regeln-in-c-gcc:

"Strict-aliasing-Regeln sind verwurzelt in Teile des Standards in C und C++ seit Anfang [standardisierten] mal. Die Klausel verbietet den Zugriff auf Objekt des Typs durch ein lvalue eines anderen Typs ist in C89/90 (6.3) als auch in C++98 (3.10/15). ... Es ist nur so, dass nicht alle Compiler wollte (oder gewagt), um ihn durchzusetzen oder sich darauf verlassen."

Gut, gcc ist jetzt gewagt, so zu tun, mit seiner -fstrict-aliasing wechseln. Und dies verursacht einige Probleme. Siehe z.B. den exzellenten Artikel http://davmac.wordpress.com/2009/10/ über ein Mysql-bug, und das ebenso ausgezeichnete Diskussion in http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html.

Einige andere weniger relevante links:

So zu wiederholen, haben Sie eine horror-Geschichte, die Ihrer eigenen? Probleme nicht gekennzeichnet durch -Wstrict-aliasing würde, natürlich, werden bevorzugt. Und andere C-Compiler sind auch willkommen.

Hinzugefügt 2. Juni: Der erste link in Michael Burr ' s Antwort, die nicht ja qualifizieren, als eine horror-Geschichte ist, ist vielleicht ein bisschen veraltet (von 2003). Ich habe einen schnellen test, aber das problem ist anscheinend Weg.

Quelle:

#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;
}

Den spezifischen Beschwerde ist:

Einige Benutzer haben sich beschwert, dass, wenn der [oben] - code kompiliert wird, ohne die -fno-strict-aliasing, die Reihenfolge der schreiben und memcpy ist invertiert (das heißt, eine Schein-len mem-kopiert in den Bach).

Kompilierten code, mit gcc 4.3.4 auf CYGWIN-wih -O3 (bitte korrigiert mich wenn ich falsch bin-mein assembler ist etwas eingerostet!):

_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
        jae L2
        movl        16(%ebp), %ecx      # iwe       --> %ecx
        movl        %edx, (%ecx)        # event_len --> iwe->len (!!)
        movl        %edx, 8(%esp)       # event_len --> stack
        movl        %ecx, 4(%esp)       # iwe       --> stack
        movl        %eax, (%esp)        # stream    --> stack
        call        _memcpy
        movl        %ebx, %eax          # sum       --> retval
L2:
        addl        $20, %esp
        popl        %ebx
        leave
        ret

Und für den zweiten link in Michaels Antwort,

*(unsigned short *)&a = 4;

gcc wird meist (immer?) geben Sie eine Warnung. Aber ich glauben eine gültige Lösung zu diesem (für gcc) ist zu verwenden:

#define CAST(type, x) (((union {typeof(x) src; type dst;}*)&(x))->dst)
//...
CAST(unsigned short, a) = 4;

Ich habe gefragt, ob das OK ist in gcc-strict-aliasing-und-casting-über-eine-unionaber bisher niemand widerspricht.

InformationsquelleAutor der Frage Joseph Quinsey | 2010-06-02

Schreibe einen Kommentar