我刚刚读到有关mode_t的信息,它基本上存储了以下信息:
所以需要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;
也许这有助于答案。
答案 0 :(得分:10)
让我们看一下“dumb”编译器在给出以下代码时会做什么:
#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");
}
这似乎是类型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
...
了解加载16位值需要特殊的movzwl
指令吗?这是因为它需要符号扩展到另外两个字节以适合寄存器。显然,这条指令比简单的mov
更复杂。这可能对性能产生很小的影响,并且可能会将可执行文件大小增加几个字节,这本身就不会太糟糕。
但是,如果我们认为使用16位值没有任何优势,因为由于对齐,它通常会占用32位存储空间,因此很明显为什么设计人员选择使用原始字大小这里的CPU。