2016-04-24 12 views
15

ich eine Vereinigung in C wie folgt aussehen:Speicher Position der Elemente in C/C++ Union

union AUnion { 
    struct CharBuf { 
    char *buf; 
    size_t len; 
    } charbuf; 
    uint8_t num; 
    double fp_num; 
}; 

Meine Frage ist, kann ich garantieren, dass die folgende wenn gegeben:

union AUnion u; 

dann die folgende Bedingungen erfüllt sind:

&u == &u.num 
&u == &u.fp_num 
&u == &u.charbuf 

Dh sie alle am Anfang des Speichersegments beginnen, wo u gespeichert wird.

Im Falle dieses C-Programm kompiliert mit gcc version 5.3.0 und -std=c11 die oben gilt:

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 

union AUnion { 
    struct CharBuf { 
     char *buf; 
     size_t len; 
    } charbuf; 
    uint8_t num; 
    double fp_num; 
}; 

int main(void) 
{ 
    union AUnion u; 
    printf("%d\n", ((void*)&u) == ((void*)&u.charbuf)); 
    printf("%d\n", ((void*)&u.charbuf) == ((void*)&u.num)); 
    printf("%d\n", ((void*)&u.num) == ((void*)&u.fp_num)); 
} 

Wie druckt:

1 
1 
1 

Kompilieren des Codes oben als C++ 11 mit der Derselbe Compiler führt zu der gleichen Ausgabe wie er als C11 kompiliert wird.

Aber ist das standardisiertes Verhalten? Ist es undefiniert? Kann ich mich bei den meisten C-Compilern auf dieses Verhalten verlassen? Kann ich dieses Verhalten auch mit C++ Compilern erwarten?

+0

C++ behandelt Union nicht anders als c –

+1

@UriBrecher tatsächlich gibt es viele Unterschiede –

+1

@ M.M: Dann sagen, dass wie "Union" unterscheidet sich in C & C++? Listen Sie die vielen Unterschiede auf Wenn Sie so denken !!! – Destructor

Antwort

13

In 6.7.2.1p16 die C-Standard garantiert, dass:

Die Größe einer Vereinigung ausreichend ist, die größte ihrer Mitglieder zu enthalten. Der Wert von höchstens einem der Mitglieder kann jederzeit in einem Union-Objekt gespeichert werden. Ein Zeiger auf ein Unionsobjekt, das entsprechend konvertiert wird, zeigt auf jedes seiner Elemente (oder wenn ein Mitglied ein Bitfeld ist, dann auf die Einheit, in der es sich befindet) und umgekehrt.

Also, ja, können Sie sich auf alle Mitglieder an der Adresse s union Start verlassen (beachten Sie, dies ist das gleiche für das erste Mitglied einer struct).

Die C++ Standard enthält einen ähnlichen Satz in Bezug auf C-Format (dh nur C-style Mitglieder) union s/struct s, weil C++ ermöglicht union s bis C Funktionen übergeben, die diesen entsprechenden Abschnitt layout.The erfordert im C++ - Standard ist 9.5.


jedoch, beachten Sie, es könnte Bits innerhalb Standard einfache Typen Klotzen (ganze Zahlen, die Schwimmer). Und ihr Inneres kann variieren (Endianess). Sie könnten auch die strenge Aliasing-Regel (C: effektiver Typ) verletzen.

9

Aus meiner Erfahrung würde ich "ja" sagen, obwohl ich die C++14 standard überprüft habe und es sogar das garantiert. (C++ 11 wird höchstwahrscheinlich die gleichen Auswirkungen haben) Kapitel 9.5 besagt: All non-static data members of a union object have the same address

Also, Sie können sich auf dieses Verhalten verlassen.

Verwandte Themen