int 位域的大小和对齐方式
size and alignment of int bitfields
具有位域的结构,即使在“打包”时,似乎也会根据指定的 int 类型处理位域的大小(以及对齐方式?)。有人可以 指出定义该行为的 C++ 规则吗? 我尝试了十几种编译器和架构(谢谢 Compiler Explorer!),结果在所有方面都是一致的。
下面是要玩的代码:
https://godbolt.org/z/31zMcnboY
#include <cstdint>
#pragma pack(push, 1)
struct S1{ uint8_t v: 1; }; // sizeof == 1
struct S2{ uint16_t v: 1; }; // sizeof == 2
struct S3{ uint32_t v: 1; }; // sizeof == 4
struct S4{ unsigned v: 1; }; // sizeof == 4
#pragma pack(pop)
auto f(auto s){ return sizeof(s); }
int main(){
f(S1{});
f(S2{});
f(S3{});
f(S4{});
}
生成的 ASM 清楚地显示 f()
返回的大小分别为 S1
、S2
、S3
的 1、2、4:
Could someone point to a C++ rule that defines that behavior?
标准没有指定任何关于 #pragma pack(push, 1)
的内容(除了 #pragma
被指定为具有实现定义含义的 pre-processor 指令)。它是一个语言扩展。
这是关于位域的标准规定:
[class.bit]
... A bit-field shall have integral or (possibly cv-qualified) enumeration type; the bit-field semantic property is not part of the type of the class member. ... 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.
基本上完全由实现定义或未指定。
bit-field 序列的最小大小是其基础类型的大小。多个相邻的相同底层类型的 bit-field 被打包到最小数量的底层类型的单词,而不分解任何 bit-field。大小为 0 的 bit-field 表示显式中断,后续字段从下一个单词开始。混合基础类型会导致在分歧点出现突破。位不是大多数机器上的最小可寻址单元,数据类型的大小以八位字节为单位测量,作为最小可寻址内存单元。
具有位域的结构,即使在“打包”时,似乎也会根据指定的 int 类型处理位域的大小(以及对齐方式?)。有人可以 指出定义该行为的 C++ 规则吗? 我尝试了十几种编译器和架构(谢谢 Compiler Explorer!),结果在所有方面都是一致的。
下面是要玩的代码: https://godbolt.org/z/31zMcnboY
#include <cstdint>
#pragma pack(push, 1)
struct S1{ uint8_t v: 1; }; // sizeof == 1
struct S2{ uint16_t v: 1; }; // sizeof == 2
struct S3{ uint32_t v: 1; }; // sizeof == 4
struct S4{ unsigned v: 1; }; // sizeof == 4
#pragma pack(pop)
auto f(auto s){ return sizeof(s); }
int main(){
f(S1{});
f(S2{});
f(S3{});
f(S4{});
}
生成的 ASM 清楚地显示 f()
返回的大小分别为 S1
、S2
、S3
的 1、2、4:
Could someone point to a C++ rule that defines that behavior?
标准没有指定任何关于 #pragma pack(push, 1)
的内容(除了 #pragma
被指定为具有实现定义含义的 pre-processor 指令)。它是一个语言扩展。
这是关于位域的标准规定:
[class.bit]
... A bit-field shall have integral or (possibly cv-qualified) enumeration type; the bit-field semantic property is not part of the type of the class member. ... 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.
基本上完全由实现定义或未指定。
bit-field 序列的最小大小是其基础类型的大小。多个相邻的相同底层类型的 bit-field 被打包到最小数量的底层类型的单词,而不分解任何 bit-field。大小为 0 的 bit-field 表示显式中断,后续字段从下一个单词开始。混合基础类型会导致在分歧点出现突破。位不是大多数机器上的最小可寻址单元,数据类型的大小以八位字节为单位测量,作为最小可寻址内存单元。