---
tags: NCKU Linux Kernel Internals, C語言
---
# C 語言:bit-field
[bit-field](https://hackmd.io/@sysprog/c-bitfield?type=view)
## bit-field
根據[C - Bit Fields](https://www.tutorialspoint.com/cprogramming/c_bit_fields.htm)的說明:
```c=
struct {
unsigned int widthValidated;
unsigned int heightValidated;
} status;
```
例如說你有一個資料結構,僅僅是想用來表示true或者false。但這樣的宣告會用掉8bytes的空間。
```c=
struct {
unsigned int widthValidated : 1;
unsigned int heightValidated : 1;
} status;
```
於是你可以透過這個寫法,僅使用4個bytes中的兩bits來紀錄即可。
## 問題
```c=
#include <stdbool.h>
#include <stdio.h>
bool is_one(int i) { return i == 1; }
int main() {
struct { signed int a : 1; } obj = { .a = 1 };
puts(is_one(obj.a) ? "one" : "not one");
return 0;
}
```
注意到上面的寫法中,程式的輸出不一定是one。因為a是signed int,因此在1 bit下可表示的範圍是`-1 ~ 0`。由於 int 並沒有說是 signed 或 unsigned ,那麼 bit-field 宣告之後究竟該是 signed / unsigned 是由編譯器所決定的。
## zero width bits
```c=
struct foo {
int a : 3;
int b : 2;
int c : 3;
};
```
```c=
struct foo {
int a : 3;
int b : 2;
int : 0; /* Force alignment to next boundary */
int c : 3;
};
```
比較一下上下兩種寫法,`int : 0`的意思是對 structure 目前的 unit 做 padding,把 bit field 對齊到下一個 unit。因此,上面的結構只需要4 bytes(1個int),然而下面會用到8 bytes(2個int)。注意到zero-width bit field 必須是未命名。
推薦閱讀這位同學更深入的研究:[zero-width bit field 問題探討 I](https://hackmd.io/@shihtiytw/ByQLhPIwE)