6

__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ものもパックされますか?

4

1 に答える 1

8

いいえ、barきつく詰めることはありません。__attribute__ ((__packed__))パックされるかのように明示的にマークする必要があります。次の例を検討してください。

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

このプログラムの出力 (gcc 4.2、64 ビットおよび clang 3.2、64 ビットでコンパイル) は次のとおりです。

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

astructとそのネストされたstructs をすべて密にパックする場合__attribute__ ((__packed__))は、それぞれに対して明示的に宣言する必要がありますstructbarの型が の外部で宣言されるようにネストを分離することを考える場合、これは理にかなっていますfoo

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

上記の例では、 forbarをパックするために、Barとして宣言する必要があります__attribute__ ((__packed__))。最初のコード例のようにネストするためにこれらの構造をコピーアンドペーストすると、パッキング動作が一貫していることがわかります。


対応する C++ コード (g++ 4.2 および clang++ 3.2 でコンパイルされ、64 ビットを対象としており、上記とまったく同じ結果が得られます):

#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;
}
于 2013-06-03T19:43:45.400 に答える