2013-06-03 6 views
5

Was ist der Effekt von __attribute__ ((__packed__)) auf verschachtelte Strukturen? Zum Beispiel:Welche Auswirkungen hat __attribute__ ((__packed__)) auf verschachtelte Strukturen?

// C version 
struct __attribute__ ((__packed__)) 
{ 
    struct 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo; 

// C++ version 
struct __attribute__ ((__packed__)) Foo 
{ 
    struct Bar 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo; 

Ich weiß foo wird eng gepackt werden, aber was ist bar? Wird es auch dicht gepackt sein? Ist __attribute__ ((__packed__)) die verschachtelte struct auch verpackt?

Antwort

7

Nein, bar wird nicht dicht gepackt. Es muss explizit als __attribute__ ((__packed__)) gekennzeichnet werden, wenn es gepackt werden soll. Man betrachte das folgende Beispiel:

#include <stdio.h> 

struct 
{ 
    struct 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo1; 

struct __attribute__ ((__packed__)) 
{ 
    struct 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo2; 

struct 
{ 
    struct __attribute__ ((__packed__)) 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo3; 

struct __attribute__ ((__packed__)) 
{ 
    struct __attribute__ ((__packed__)) 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo4; 

int main() 
{ 
    printf("sizeof(foo1): %d\n", (int)sizeof(foo1)); 
    printf("sizeof(foo2): %d\n", (int)sizeof(foo2)); 
    printf("sizeof(foo3): %d\n", (int)sizeof(foo3)); 
    printf("sizeof(foo4): %d\n", (int)sizeof(foo4)); 

    return 0; 
} 

Die Ausgabe dieses Programms (Kompilieren mit gcc 4.2, 64-Bit und Klappern 3,2, 64-Bit) ist:

sizeof(foo1): 16 
sizeof(foo2): 13 
sizeof(foo3): 12 
sizeof(foo4): 10 

Wenn ein struct und seine verschachtelte struct s sind alle dicht gepackt, __attribute__ ((__packed__)) muss explizit für jede struct deklariert werden. Dies macht Sinn, wenn Sie die Verschachtelung der Abtrennung denken, so dass bar ‚s Art außerhalb von foo erklärt wird, etwa so:

// Note Bar is not packed 
struct Bar 
{ 
    char c; 
    int i; 
}; 

struct __attribute__ ((__packed__)) 
{ 
    // Despite foo being packed, Bar is not, and thus bar will not be packed 
    struct Bar bar; 
    char c; 
    int i; 
} foo; 

In dem obigen Beispiel für bar, verpackt werden Bar müssen deklariert werden __attribute__ ((__packed__)). Wenn Sie diese Strukturen kopieren, um sie wie im ersten Codebeispiel zu verschachteln, sehen Sie, dass das Packungsverhalten konsistent ist.


entsprechende C++ Code (mit g ++ kompiliert 4.2 und Klappern ++ 3.2, Targeting-64-Bits, die genau die gleichen Ergebnisse wie oben erhalten):

#include <iostream> 

struct Foo1 
{ 
    struct Bar1 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo1; 

struct __attribute__ ((__packed__)) Foo2 
{ 
    struct Bar2 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo2; 

struct Foo3 
{ 
    struct __attribute__ ((__packed__)) Bar3 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo3; 

struct __attribute__ ((__packed__)) Foo4 
{ 
    struct __attribute__ ((__packed__)) Bar4 
    { 
     char c; 
     int i; 
    } bar; 

    char c; 
    int i; 
} foo4; 

int main() 
{ 
    std::cout << "sizeof(foo1): " << (int)sizeof(foo1) << std::endl; 
    std::cout << "sizeof(foo2): " << (int)sizeof(foo2) << std::endl; 
    std::cout << "sizeof(foo3): " << (int)sizeof(foo3) << std::endl; 
    std::cout << "sizeof(foo4): " << (int)sizeof(foo4) << std::endl; 
} 
Verwandte Themen