我刚刚读到了有关 mode_t 的内容,它基本上存储了以下信息:
- 文件类型的 7 个布尔值(S_IFREG、S_IFDIR、S_IFCHR、S_ISBLK、S_ISFIFO、S_ISLINK、S_ISSOCK)
- 3*3 = 9 个布尔值,用于访问权限(所有者、组和其他人的读、写和执行)
所以需要16位=2字节。我想你甚至可以少一点文件类型,因为它必须是常规文件、目录、字符或块设备、套接字、符号链接或管道。或者是否存在其他文件类型?
所以我刚刚检查了 mode_t 的大小
printf("Size: %d byte\n", sizeof(mode_t));
它使用 4 字节。为什么使用4字节?还有什么我没注意到的额外信息吗?
编辑:
我刚刚发现 mode_t 在 ptypes.inc 中定义:
type mode_t = cuint32;
cuint32 是一个 32 位大小的无符号整数,在 ctypes.inc 中定义:
type cuint32 = LongWord;
也许这有助于找到答案。
让我们看看“哑”编译器在给出以下代码时会做什么:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint16_t test1 = 0x1122;
uint32_t test2 = 0x11223344;
if (test1 & 0x0100)
printf("yay1.\n");
if (test2 & 0x00010000)
printf("yay2.\n");
}
这似乎是 type 值的可能用例mode_t
,检查是否设置了标志。现在我们编译它gcc -O0
并检查生成的程序集:
0000000000000000 <main>:
...
f: 66 c7 45 fe 22 11 movw $0x1122,-0x2(%rbp)
15: c7 45 f8 44 33 22 11 movl $0x11223344,-0x8(%rbp)
1c: 0f b7 45 fe movzwl -0x2(%rbp),%eax ; load test1 into %eax
20: 25 00 01 00 00 and $0x100,%eax
25: 85 c0 test %eax,%eax
...
33: 8b 45 f8 mov -0x8(%rbp),%eax ; load test2 into %eax
36: 25 00 00 01 00 and $0x10000,%eax
3b: 85 c0 test %eax,%eax
...
看看如何特别movzwl
需要指令来加载16位值吗?这是因为它需要符号扩展为两个附加字节才能适合寄存器。显然这个指令比简单的指令更复杂mov
。这可能会对性能产生微小的影响,并且可能会增加可执行文件的大小一些字节,这本身并不会太糟糕。
然而,如果我们认为使用 16 位值没有任何优势,因为由于对齐,它通常会占用 32 位存储空间,那么设计者为什么选择在这里使用 CPU 的本机字大小就很清楚了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)