2012-03-07 3 views
6

私はちょうどそれが基本的には次の情報が格納されていることmode_tについて読んだ:ファイルタイプのなぜmode_tは4バイトを使用しますか?

  • 7ブール値(S_IFREG、S_IFDIR、S_IFCHR、S_ISBLK、S_ISFIFO、S_ISLINK、S_ISSOCK)
  • 3 * 3 = 9アクセス許可のブール値(所有者、グループおよび他の人のための読み込み、書き込み、実行)

したがって、16ビット= 2バイトが必要です。普通のファイル、ディレクトリ、文字またはブロックデバイス、ソケット、シンボリックリンク、またはパイプのいずれかでなければならないので、ファイルタイプのビット数を1ビット少なくすることもできます。それとも他のファイルタイプが存在するのですか?

だから、僕はそれは4バイトを使用しています

printf("Size: %d byte\n", sizeof(mode_t)); 

でmode_tのサイズをチェックしました。なぜ4バイトを使用していますか?私が気付かなかった追加の情報はありますか?

編集:

type mode_t = cuint32; 

cuint32 32ビットは大きさで、符号なし整数とctypes.incで定義された:

type cuint32 = LongWord; 
私はmode_tがptypes.incに定義されていることを見つけた

これはおそらく答えに役立ちます。

+1

将来追加オプション/フラグなどを追加する必要がある場合はどうすればよいですか? – Nim

+0

ほとんどのアーキテクチャでは32ビットである 'int'から単純にtypedefされている可能性があります。それは将来の旗に合うように大きくなっています。 –

+0

** int ** type _may_に「255」という数字を格納しても4バイトになる可能性があります... 「ビルディングブロック」はプロセッサアーキテクチャであり、さらに他のフラグのための空き領域があります必要。 OMG私はbitflagsが嫌い! –

答えて

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ビットの値をロードするために必要とされている方法を参照してください?これは、レジスタに収まるように2つの追加バイトに符号拡張する必要があるためです。明らかに、この命令は単純なmovより複雑です。これはパフォーマンスにはあまり影響を及ぼさないかもしれませんし、実行可能なサイズを何バイトか増加させるかもしれません。

しかし、16ビット値を使用する利点はないと考えても、アライメントのために通常は32ビットの記憶域が必要になるため、設計者がネイティブワードサイズここにCPUの。

関連する問題