2013-06-03 28 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__))。考慮下面的例子:

#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比特和鐺3.2,64位編譯)的輸出是:

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

如果struct及其嵌套struct s都要緊緊包裝,__attribute__ ((__packed__))必須明確聲明每個struct。這是有道理的,如果你想使bar的類型聲明的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; 

在上面的例子中,爲bar進行包裝,Bar必須聲明爲__attribute__ ((__packed__))。如果您要複製'n'粘貼這些結構以便像第一個代碼示例中那樣嵌套它們,您將看到包裝行爲是一致的。


通訊C++代碼(用克++ 4.2和鐺++ 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; 
}