2012-03-07 88 views
6

我刚刚看了一下mode_t,它主要存储以下信息:文件类型(S_IFREG,S_IFDIR,S_IFCHR,S_ISBLK,S_ISFIFO,S_ISLINK,S_ISSOCK) 为什么mode_t使用4个字节?

  • 3 *

    • 7布尔值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; 
    

    也许这有助于答案。

  • +1

    如果将来需要添加更多选项/标志等,该怎么办? – Nim 2012-03-07 13:50:31

    +0

    这可能是因为它只是从一个'int'中定义的类型,这在大多数体系结构中都是32位。或者它变得更大,因此它可以适应未来的标志。 – 2012-03-07 13:50:48

    +0

    你** ** INT型_may_为4个字节,即使你在它存储的号码“255” ...... 的“积木”,是处理器架构,而且你对他们将任何其他标志一些自由空间需要。 OMG我恨bitflags! – 2012-03-07 13:51:00

    回答

    9

    让我们来看看什么时候给下面的代码“哑”编译器会做:

    #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 
          ... 
    

    见特别movzwl指令是如何需要加载16位值?这是因为它需要符号扩展到两个额外的字节以适应寄存器。显然,这条指令比简单的mov更复杂。这可能会对性能产生很小的影响,并且可能会将可执行文件的大小增加一些字节,这本身不会太糟糕。但是,如果我们认为使用16位值不会有任何优势,因为它通常会由于对齐而占用32位存储空间,这很明显为什么设计人员选择使用本机字大小的CPU在这里。

    相关问题