qwe*_*rtz 4 c gcc struct unions bit-fields
我想知道为什么bitfields与unions/structs一起工作,但是没有像int或那样的普通变量short.
这有效:
struct foo {
int bar : 10;
};
Run Code Online (Sandbox Code Playgroud)
但这失败了:
int bar : 10; // "Expected ';' at end of declaration"
Run Code Online (Sandbox Code Playgroud)
为什么此功能仅在联合/结构中可用而不在变量中?技术不一样吗?
编辑:
如果允许,你可以创建一个3字节的变量,而不是每次都使用struct/union成员.这就是我对结构的看法:
struct int24_t {
int x : 24 __attribute__((packed));
};
struct int24_t var; // sizeof(var) is now 3
// access the value would be easier:
var.x = 123;
Run Code Online (Sandbox Code Playgroud)
这是一个主观问题,"为什么规范说这个?" 但我会试一试.
函数中的变量通常具有"自动"存储,而不是其他持续时间之一(静态持续时间,线程持续时间和分配的持续时间).
在结构中,您明确定义某个对象的内存布局.但是在函数中,编译器会自动以某种未指定的方式将存储分配给变量.这是一个问题:x堆栈上占用了多少字节?
// sizeof(unsigned) == 4
unsigned x;
Run Code Online (Sandbox Code Playgroud)
它可能占用4个字节,或者它可能占用8个,12个或0个,或者它可以同时放在三个不同的寄存器中,或者堆栈和寄存器,或者它可以在堆栈上获得四个位置.
关键是编译器正在为您进行分配.由于您没有进行堆栈布局,因此不应指定位宽.
扩展讨论: Bitfield实际上有点特殊.规范声明相邻的位域被打包到同一个存储单元中.位域实际上不是对象.
你不能sizeof()有点野外.
你不能malloc()有点野外.
你不能&addressof有点野外.
所有这些都可以用C语言中的对象完成,但不能用位域.Bitfields是一种特殊的东西,仅用于结构而不是其他任何地方.
关于int24_t(更新):它适用于某些体系结构,但不适用于其他体系结构.它甚至没有轻微的便携性.
typedef struct {
int x : 24 __attribute__((packed));
} int24_t;
Run Code Online (Sandbox Code Playgroud)
在Linux ELF/x64,OS X/x86,OS X/x64 , sizeof(int24_t) == 3. 但是在OS X/PowerPC上,sizeof(int24_t) == 4.
注意GCC为加载生成的代码int24_t基本上等同于:
int result = (((char *) ptr)[0] << 16) |
(((unsigned char *) ptr)[1] << 8) |
((unsigned char *)ptr)[2];
Run Code Online (Sandbox Code Playgroud)
这是x64上的9条指令,只是为了加载一个值.