Linux-Kernel-Internals - Linux Kernel Internals: https://ankitkdev.com/blog/ - Char Driver: https://ankitkdev.com/blog/linux-kernel/device-driver/char-driver/ - Ioctl Interface: https://ankitkdev.com/blog/linux-kernel/device-driver/ioctl/ - Proc-Interface: https://ankitkdev.com/blog/linux-kernel/device-driver/proc/ - Completion-Variable: https://ankitkdev.com/blog/linux-kernel/concurrency/completion-variable/ - container_of(): https://ankitkdev.com/blog/linux-kernel/macros/container_of/ - Module Parameters: https://ankitkdev.com/blog/linux-kernel/macros/kernel-module/ - pr_fmt(): https://ankitkdev.com/blog/linux-kernel/macros/pr-family/ - Stringification: https://ankitkdev.com/blog/linux-kernel/macros/string/ - Debugging Macros: https://ankitkdev.com/blog/linux-kernel/macros/debug/ - Error Handling with Pointers: https://ankitkdev.com/blog/kernal-internals/error-handling/ - Kbuild Makefile: https://ankitkdev.com/blog/kernal-internals/kbuild/ - SLUB debug: https://ankitkdev.com/blog/kernel-debugging/debug-slub-memory/ - unsigned :\ 0 Bit-Fields in c: https://ankitkdev.com/blog/c/zero-width-bit-field/ - do { ... } while (0): https://ankitkdev.com/blog/c/do-while-loop/ - Error Handling: https://ankitkdev.com/blog/c/error-handling/ - C Memory Layout: https://ankitkdev.com/blog/c/c-memory-layout/ - Forward Declarations: https://ankitkdev.com/blog/c/forward-declaration-in-c/ - Return value by Macro: https://ankitkdev.com/blog/c/return-by-macro/ - Variadic Macro: https://ankitkdev.com/blog/c/variadic-macro/ - programming concepts: https://ankitkdev.com/blog/theory/ - Build & Install Linux Kernel for BBB: https://ankitkdev.com/blog/misc/build-linux-kernel-BBB/ - Configure U-boot for BBB: https://ankitkdev.com/blog/misc/configure-uboot-bbb/ - Install Ubuntu Server on Qemu: https://ankitkdev.com/blog/misc/install-ubuntu-server-on-qemu/ - Linux Kernel Mentorship Program: https://ankitkdev.com/blog/misc/linux-kernel-mentorship-program/ ### `unsigned : 0` in C Bit-Fields > Sometimes We have particular case, where a field must begin at the next word boundary, so a zero-width bit-field is used. Consider the following structure: ```c struct test { unsigned a : 3; unsigned b : 5; unsigned c : 6; }; ``` member of this struct uses only **14 bits** in total (3 + 5 + 6). However, on most systems, `sizeof(struct test)` gives **4 bytes**, not 14 bits. Because unsigned bit-fields are allocated inside an unsigned int storage unit. If unsigned int is 32 bits, all 14 bits fit into a single 32-bit storage unit. Typical layout: ``` | a(3) | b(5) | c(6) | unused(18) | ------------------------------------ one 32-bit unit ``` Now consider: ```c struct test { unsigned a : 3; unsigned b : 5; unsigned : 0; unsigned c : 6; }; ``` The unnamed zero-width bit-field (`unsigned : 0;`) tells the compiler: > Start the next bit-field at the beginning of a new allocation unit. Layout becomes: ``` 32-bit unit #1: | a(3) | b(5) | unused(24) | 32-bit unit #2: | c(6) | unused(26) | ``` As a result, the structure typically occupies **8 bytes**. **Important Note** This behavior is **not a compiler optimization**. The C standard leaves bit-field layout as **implementation-defined**, and most compilers choose to allocate `unsigned` bit-fields inside `unsigned int` storage units. So, `unsigned : 0;` acts as a **boundary marker**, forcing the next bit-field into a new storage unit.