__attribute __((__ package___))对嵌套结构的影响是什么?

Cor*_*lks 5 c c++ gcc g++

__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;
Run Code Online (Sandbox Code Playgroud)

我知道foo会紧紧包装,但是怎么样bar?它会紧紧包装吗?是否__attribute__ ((__packed__))使嵌套struct也包装好?

Cor*_*lks 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;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出(使用gcc 4.2,64位和clang 3.2,64位编译)是:

sizeof(foo1): 16
sizeof(foo2): 13
sizeof(foo3): 12
sizeof(foo4): 10
Run Code Online (Sandbox Code Playgroud)

如果a struct和它的嵌套structs都要紧密打包,则__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;
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,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;
}
Run Code Online (Sandbox Code Playgroud)