2013-06-03 11 views
5

__attribute__ ((__packed__))がネストした構造体に与える影響は?たとえば、次のように__attribute__((__packed__))がネストした構造体に与える影響は何ですか?

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

私はfooが密に充填されますが、知っているbarについて何?あまりにもしっかりとパックされますか? __attribute__ ((__packed__))ネストされたstructもパックされていますか?

答えて

7

いいえ、barはしっかりと詰め込まれません。パックする場合は、明示的に__attribute__ ((__packed__))のマークを付ける必要があります。このプログラム(GCC 4.2でコンパイル、64ビットと打ち鳴らす3.2、64ビット)の出力である

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

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

structstructそのネストされた場合は、次の例を考えてみますすべてがきつく詰まっているため、structごとに__attribute__ ((__packed__))を明示的に宣言する必要があります。上記の例では

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

barをパックするために、Barは次のように宣言する必要があります:あなたはbarのタイプは、fooの外で宣言さそうのようになるようにネスティングを分離を考える場合、これは、理にかなっています__attribute__ ((__packed__))。最初のコード例のようにこれらの構造を貼り付けるために 'n'をコピーすると、パッキングの振る舞いが一貫していることがわかります。 (上記のようにまったく同じ結果が得られる64ビットを標的G ++ 4.2と打ち鳴らす++ 3.2でコンパイル、、)


対応するC++コード:

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