2013-06-03 13 views
5

Jaki jest efekt __attribute__ ((__packed__)) dla zagnieżdżonych struktur? Na przykład:Jaki jest efekt __attribute__ ((__packed__)) w zagnieżdżonych strukturach?

// 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; 

wiem foo będzie ciasno, ale co bar? Czy to też będzie mocno zapakowane? Czy __attribute__ ((__packed__)) jest również pakowany w zagnieżdżone struct?

Odpowiedz

7

Nie, bar nie będzie ściśle spakowany. Musi być wyraźnie oznaczony jako __attribute__ ((__packed__)), jeśli ma być spakowany. Rozważmy następujący przykład:

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

wyjście z tego programu (kompilacja z gcc 4.2, 64-bitów i brzękiem 3.2, 64-bitów) wynosi:

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

Jeżeli struct i zagnieżdżonych struct s muszą być szczelnie zapakowane, __attribute__ ((__packed__)) musi być jawnie zadeklarowane dla każdego struct. Ma to sens, jeśli myślisz o oddzielenie zagnieżdżania się tak, że typ bar „s jest zadeklarowana poza foo, tak:

// 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; 

W powyższym przykładzie, dla bar być pakowane, Bar muszą być zadeklarowane jako __attribute__ ((__packed__)). Jeśli skopiowałeś 'n' wklejesz te struktury, aby je zagnieździć jak w pierwszym przykładzie kodu, zobaczysz, że zachowanie podczas pakowania jest spójne.


Odpowiedni kod C++ (przygotowana z 4,2 g ++ ++ i brzękiem 3.2 kierowania 64 bitów, co daje te same wyniki, jak wyżej)

#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; 
} 
Powiązane problemy