ISO/IEC 14882:2003: 9.6 Bit-fields [class.bit]
- A member-declarator of the form identifieropt : constant-expression specifies a bit-field; its length is set off from the bit-field name by a colon. The bit-field attribute is not part of the type of the class member. The constant-expression shall be an integral constant-expression with a value greater than or equal to zero. The constant-expression may be larger than the number of bits in the object representation (3.9) of the bit-field’s type; in such cases the extra bits are used as padding bits and do not participate in the value representation (3.9) of the bit-field. Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit. [Note: bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. ]
- A declaration for a bit-field that omits the identifier declares an unnamed bit-field. Unnamed bit-fields are not members and cannot be initialized. [Note: an unnamed bit-field is useful for padding to conform to externally-imposed layouts. ] As a special case, an unnamed bit-field with a width of zero specifies alignment of the next bit-field at an allocation unit boundary. Only when declaring an unnamed bit-field may the constant-expression be a value equal to zero.
- A bit-field shall not be a static member. A bit-field shall have integral or enumeration type (3.9.1). It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned. A bool value can successfully be stored in a bit-field of any nonzero size. The address-of operator & shall not be applied to a bit-field, so there are no pointers to bit-fields. A non-const reference shall not be bound to a bit-field (8.5.3). [Note: if the initializer for a reference of type const T& is an lvalue that refers to a bit-field, the reference is bound to a temporary initialized to hold the value of the bit-field; the reference is not bound to the bit-field directly. See 8.5.3. ]
- If the value true or false is stored into a bit-field of type bool of any size (including a one bit bitfield), the original bool value and the value of the bit-field shall compare equal. If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type, the original enumerator value and the value of the bit-field shall compare equal.
最近在64bit IOS上遇到一个问题, 发现bit field的数据不对. 这个bit field是一个data struct, 在host(win32)上生成. 运行时候发现IOS取的值不对.
比如
struct { int a : 4; int b : 8; int c : 16; int d : 8; int e : 16; };
在IOS的32位上, d会横跨两个allocation uint, 而在IOS的64位上, d从第二个allocation unit上从新开始. 根据C++标准, 这个是implementation defined, 可以横跨也可以不横跨. 所以严格来说也不算clang的bug. 只要将a,b,c对齐到32bit的整数, 这样强制d从新的allocation unit开始, 没有横跨的问题, 对于IOS32位和IOS64位都有效.
IOS 64bit的额外参考: 对齐等等其他因素
个人觉得bitfield用在game data里面会有平台的问题, 所以blade里面没有用过. 而公司的代码用的地方非常多, 这个是历史原因.
时间: 2024-10-16 14:24:49