1

最近、libuvのソースを読みました。QUEUE.h を読むときにいくつか質問があります

まず: 以下のマクロ定義:</p>

typedef void *QUEUE[2];
#define QUEUE_NEXT(q)       (*(QUEUE **) &((*(q))[0]))
#define QUEUE_PREV(q)       (*(QUEUE **) &((*(q))[1]))

QUEUE_PREV(q) を次のように再定義できますか。

#define QUEUE_PREVR(q)       ((QUEUE *) &((*(q))[1]))

それらの違いは何ですか?

第二に: 私は以下のコードを試します:

typedef struct{
     int i1;
     int i5 ;
     int i6;
}s1;

typedef struct 
{
    int j1;
    int j2;
    int j3;
}s2;

s1 i = { 1, 2 ,61};
s2 j = { 97, 99, 90 };
QUEUE a;
a[0] = &i;
a[1] = &j;
cout << (QUEUE*)(&((*(&a))[1])) << endl;
cout << *(QUEUE*)(&((*(&a))[1])) << endl;

結果はコンソールでも同じですが、なぜですか? 「*」は機能しませんか?? このコードはVS2013で書いています。

4

1 に答える 1

3

まず、それらの違いは何ですか?

型は同じというのは正しいが、値はどうか。得られたものを見てみましょう。

QUEUE は void へのポインターの配列 2 として typedef されます

わかりました、どうですか:&((*(q))[1]))

  • qであるを取るQUEUE*
  • qを生成する逆参照QUEUE
  • void *次に、前の要素を指している2 番目の要素にインデックスを付けます。QUEUE
  • 次に、そのポインターのアドレスを取得します( a を生成しますvoid**)。

typeの結果&rを呼び出しましょう。rvoid*


#define QUEUE_PREV(q) (*(QUEUE **) &r)

&rこれは にvoid**キャストされQUEUE **ます。次に、そのまま逆参照されます。QUEUE*つまり、結果には valuerと typeQUEUE*があります。


ここまでは順調ですね。それはあなたの試みとどう違うのですか?

#define QUEUE_PREVR(q) ((QUEUE *) &r)

&r(a void **) を a にキャストしQUEUE*ます。これは合法ですが、存在していた間接化が失われました。結果には value&rと typeQUEUE*があります。タイプは同じですが、値は異なります。


第二に、「*」が機能しないのはなぜですか?

cout << (QUEUE*)&aa << endl;
cout << *(QUEUE*)&aa << endl;

最初の行ではcout&rポインタです。したがって、ポインターの値が出力されます。2 行目では、配列であるcoutaを使用します。QUEUEの外部で配列を使用すると、sizeof常に結果が最初の要素 ( &r[0]) へのポインターに変換されます。そして、私たちはそれを知ってい&r == &r[0]ます。

ついに、

QUEUEsrc/threadpool.cそのように使用することを意図したものではありません。代わりにユースケースを確認してください。

于 2015-03-29T17:46:25.600 に答える