gpt4 book ai didi

c - 位域如何在 C 中工作?

转载 作者:太空宇宙 更新时间:2023-11-04 01:03:47 26 4
gpt4 key购买 nike

我刚刚了解了 C 中的位域,我开始好奇编译器是如何实现这个特性的。就我对 C 编译器的了解而言,无法单独访问单个位。

最佳答案

位域是通过读取周围的可寻址内存单元(字节或字)、屏蔽和移位来实现的。

更准确地说,读取一个位域被实现为读移位掩码,写入一个位域被实现为读掩码移位值以写或写。

这是相当昂贵的,但如果您打算紧凑地存储数据并愿意为按位操作付出代价,那么位字段在源代码级别为您可以拥有的相同操作提供更清晰、更轻便的语法手写的。您失去的是对布局的控制(标准没有指定如何从包含字分配位字段,这在不同编译器之间的差异比按位运算的含义更大)。

每当您对 C 编译器对给定结构的作用有疑问时,您总是可以阅读汇编代码:

struct s { 
unsigned int a:3;
unsigned int b:3;
} s;

void f(void)
{
s.b = 5;
}

int g(void)
{
return s.a;
}

这是由 gcc -O -S 编译为:

_f:                                     ## @f
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
movq _s@GOTPCREL(%rip), %rax
movb (%rax), %cl ; read
andb $-57, %cl ; mask
orb $40, %cl ; since the value to write was a constant, 5, the compiler has pre-shifted it by 3, giving 40
movb %cl, (%rax) ; write
popq %rbp
retq
.cfi_endproc

.globl _g
.align 4, 0x90
_g: ## @g
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp7:
.cfi_def_cfa_offset 16
Ltmp8:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp9:
.cfi_def_cfa_register %rbp
movq _s@GOTPCREL(%rip), %rax
movzbl (%rax), %eax
andl $7, %eax
popq %rbp
retq
.cfi_endproc

关于c - 位域如何在 C 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29059168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com