C语言中编译器如何识别位字段有效位以实现二进制数据解析?
关于C语言位字段与Postgres ItemIdData的疑问
我正在通过编写Postgres克隆学习C语言,目前对编译器处理位字段的机制存在疑惑,具体围绕Postgres的行指针结构体ItemIdData中的位字段展开:
typedef struct ItemIdData { unsigned lp_off:15, /* offset to tuple (from start of page) */ lp_flags:2, /* state of line pointer, see below */ lp_len:15; /* byte length of tuple */ } ItemIdData;
我能正确设置这些字段的值并写入磁盘,但不理解编译器在将其转换为整数类型时,如何知晓15位中哪些是有效位。我编写了完整示例代码:
#include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <unistd.h> typedef struct ItemIdData { unsigned lp_off:15, /* offset to tuple (from start of page) */ lp_flags:2, /* state of line pointer, see below */ lp_len:15; /* byte length of tuple */ } ItemIdData; int main() { ItemIdData* lp = malloc(sizeof(ItemIdData)); lp->lp_off = 205; lp->lp_len = 51; int fd = open("line_pointer.data", O_RDWR | // Read/Write mode O_CREAT, // Create file if it doesn't exist S_IWUSR | // User write permission S_IRUSR // User read permission ); write(fd, lp, 4); close(fd); free(lp); ItemIdData* lp2 = malloc(sizeof(ItemIdData)); int fd2 = open("line_pointer.data", O_RDWR | // Read/Write mode O_CREAT, // Create file if it doesn't exist S_IWUSR | // User write permission S_IRUSR // User read permission ); read(fd2, lp2, 4); printf("lp_off: %d\n", lp2->lp_off); printf("lp_len: %d\n", lp2->lp_len); close(fd2); free(lp2); return EXIT_SUCCESS; }
编译运行后输出:
$ gcc -o lp main.c && ./lp lp_off: 205 lp_len: 51
通过xxd -b查看二进制文件内容为:
11001101 00000000 01100110 00000000
其中lp_off对应前15位11001101 0000000,转换为十进制是205;lp_len对应后15位1100110 00000000,转换为十进制是51。
我困惑的是:编译器在printf语句中将其转换为整数时,如何知道哪些尾零位不属于字段值?我的开发环境是WSL中的Ubuntu 20.04。
内容的提问来源于stack exchange,提问作者Chris Burke
相关产品推荐
相关产品推荐

