3

Clang 3.3 を使用して MUSL C ライブラリをコンパイルし、生成された LLVM IR ファイルをダンプしました。FILE 構造体であることがわかりました

struct __FILE_s {
    unsigned flags;
    unsigned char *rpos, *rend;
    int (*close)(FILE *);
    unsigned char *wend, *wpos;
    unsigned char *mustbezero_1;
    unsigned char *wbase;
    size_t (*read)(FILE *, unsigned char *, size_t);
    size_t (*write)(FILE *, const unsigned char *, size_t);
    off_t (*seek)(FILE *, off_t, int);
    unsigned char *buf;
    size_t buf_size;
    FILE *prev, *next;
    int fd;
    int pipe_pid;
    long lockcount;
    short dummy3;
    signed char mode;
    signed char lbf;
    int lock;
    int waiters;
    void *cookie;
    off_t off;
    char *getln_buf;
    void *mustbezero_2;
    unsigned char *shend;
    off_t shlim, shcnt;
};

としてコンパイルされました

%struct.__FILE_s = type { i32, i8*, i8*, 
i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, 
i64 (%struct.__FILE_s*, i8*, i64)*, 
i64 (%struct.__FILE_s*, i8*, i64)*, 
i64 (%struct.__FILE_s*, i64, i32)*, 
i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, 
i32, i32, i64, i16, i8, i8, i32, i32, i8*, 
i64, i8*, i8*, i8*, i64, i64 }

いくつかのIRファイルに含まれていますが、次のようにコンパイルされました

%struct.__FILE_s = type { i32, i8*, i8*, 
i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, 
i64 (%struct.__FILE_s*, i8*, i64)*, 
{}*, 
i64 (%struct.__FILE_s*, i64, i32)*, 
i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, 
i32, i32, i64, i16, i8, i8, i32, i32, i8*, 
i64, i8*, i8*, i8*, i64, i64 }

他のソース ファイルで。これら 2 つの IR 構造体の唯一の違いは、最初の形式の関数ポインター型フィールドが完全な型ではなく {}* に置き換えられていることです。なぜこれが起こるのか、また {}* 置換を無効にする方法を誰か教えてもらえますか?

4

2 に答える 2

2

これは Clang の既知のバグです。

ただし、Clang を自分でビルドし、そのバグで説明されているパッチを適用する以外に、それを回避する方法はわかりません(ただし、何らかの理由でパッチがコミットされていないことに注意してください)。

于 2013-09-11T05:52:44.260 に答える
0

ここで起こっていることのより簡単な例として、次のことができます。

struct thing;
int do_work(struct thing *to_this);

そして、コンパイラーはもののタイプを知りませんが、オペランドのサイズだけを気にするので、これをヘッダーファイルで使用できます(これはポインターであるため、何を指していてもポインターの長さのバイトになります)。

同じことがmusl cライブラリで起こっているようです。一部のコンパイル単位では型全体が定義されており、特定の型へのアクセスを必要としない他のコンパイル単位では、それがポインターであるということだけがわかっています。

完全な型の定義を含むヘッダー ファイルをインクルードする型を前方宣言するのではなく、修正は簡単です。これをしないでください。これを行うことでコンパイル時間が長くなり、最終的な実行可能ファイルの肥大化がさらに悪化する可能性があります。まさにmuslが避けるために書かれていること。コンパイル単位が完全な型を気にしない場合、完全な型についてはわかりません。ただし、すべてが正しく機能します。

于 2013-09-11T01:10:55.660 に答える