【问题标题】:C++ Substructure Bitfield SizeC++ 子结构位域大小
【发布时间】:2013-07-04 06:52:10
【问题描述】:

考虑以下几点:

class A { public:
    int     gate_type :  4;
    bool storage_elem :  1;
    uint8_t privilege :  2;
    bool      present :  1;
} __attribute__((packed));

class B { public:
    struct Sub {
        int     gate_type :  4;
        bool storage_elem :  1;
        uint8_t privilege :  2;
        bool      present :  1;
    } type_attr; //Also tried with "__attribute__((packed))" here in addition to outside
} __attribute__((packed));

编译器是 g++ 4.8.1。大小(A)==1,大小(B)==4。为什么会这样?我需要结构 B 之类的大小为 1。

【问题讨论】:

标签: c++ bit-fields


【解决方案1】:

这似乎是一个愚蠢的反问。当我将您的示例重写为时,我得到了您想要的结果:

class A { public:
    int     gate_type :  4;
    bool storage_elem :  1;
    uint8_t privilege :  2;
    bool      present :  1;
} __attribute__((packed));

class B { public:
    A type_attr; //Also tried with "__attribute__((packed))" here in addition to outside
};

是否有某些原因您不能在 class B 中重用 class A 的定义?这似乎确实是更好的方法。

我记得,C 和 C++ 都不能保证 struct Subclass A 具有相同的布局和相同的存储要求,尽管具有相同的字段宽度、顺序等。 (在 C 的情况下,它是 struct Substruct A,但同样的想法也成立,因为这些都是 POD 类型。)

确切的行为应该依赖于 ABI。不过,通过像我上面所做的那样重用class A,我认为你会让自己对 ABI 问题稍微免疫一些。 (轻微,不透水。)

【讨论】:

  • "C 和 C++ 都不保证..." - 有点不相关,因为 __attribute__((packed)) 是编译器特定的扩展;)
  • 这将是一个可以接受的解决方法,+1,尽管对于满分,我想知道为什么我的方法行不通。关于 ABI:它稍微复杂一些——这 ismaking 操作系统的上下文中 :-)
  • __attribute__ 只是对编译器的非标准提示。如果有的话,它应该削弱标准所做的保证,除非它明确地使这种保证更严格。无论如何,直接在class B 中使用class A 可以获得预期的效果,至少在x86-64 ABI 下是这样。
  • @Ian Mallett:老实说:我不确定我们在这里遇到了哪些 ABI 细节。当我将__attribute__((packed)) 应用于内部和外部struct / class 定义时,sizeof(B) 返回所有事物中的 2。荒野。请注意,在该示例中,我打破了嵌套 Sub 定义,不再声明该类型的类属性:class B { public: struct Sub { int gate_type : 4; bool storage_elem : 1; uint8_t 特权:2;布尔存在:1; } 属性((打包));子类型_attr; };
猜你喜欢
  • 2011-02-08
  • 2016-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
相关资源
最近更新 更多