2012-03-07 91 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在這裏。

    相關問題