__attribute__((__packed__))对于嵌套结构体有什么影响?

7
< p > __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也被打包吗?
1个回答

9
不,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

如果一个结构体及其嵌套的结构体都需要紧密打包,每个结构体都必须明确声明__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;

在上面的例子中,要让bar被打包,Bar必须声明为__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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接