【问题标题】:What's the effect of __attribute__ ((__packed__)) on nested structs?__attribute__ ((__packed__)) 对嵌套结构有什么影响?
【发布时间】:2013-06-03 19:43:45
【问题描述】:

__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 也被打包?

【问题讨论】:

    标签: c++ c gcc g++


    【解决方案1】:

    不,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-bits 和 clang 3.2, 64-bits 编译)是:

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

    如果struct 及其嵌套的structs 都被紧密打包,则必须为每个struct 显式声明__attribute__ ((__packed__))。这是有道理的,如果您考虑将嵌套分开,以便在 foo 之外声明 bar 的类型,如下所示:

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

    在上面的例子中,要打包barBar 必须声明为__attribute__ ((__packed__))。如果您要复制“n”粘贴这些结构以便像在第一个代码示例中那样嵌套它们,您会看到打包行为是一致的。


    对应的 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-18
      • 2015-11-19
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2016-01-30
      • 2013-07-05
      相关资源
      最近更新 更多