1

Linux カーネルで container_of マクロを使用しようとしました。

私がグーグルで得たものは次のとおりです

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) \
({ const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
 (type *)( (char *)__mptr - offsetof(type,member) );})

#define CONT(prt, type, mem) container_of((prt), type, mem)

struct test {
 int a;
};

struct m {
 int b;
 struct test t;
 int c;
};

int main(int argc, char *argv[])
{
 /* existing structure */
 struct m *ma;
 ma = malloc(sizeof(struct m));
 ma->t.a = 5;
 ma->b = 3;
 /* pointer to existing entry */    
 struct test *te = &ma->t;

 struct m *m = CONT(te, struct m, t);

 printf("m->b = %d\n", m->b);

 return EXIT_SUCCESS;
}

o/p m->b = 3

しかし、* m の割り当てに疑問があります。次のことを試しました

#include <stdio.h>

int main()
{
        int x = (int k = 9;k-2;);
        printf("x= %d k = %d",x,k);
}

o/p

one.c:5: error: expected ‘)’ before ‘k’
one.c:5: error: expected expression before ‘;’ token
one.c:6: error: ‘k’ undeclared (first use in this function)
one.c:6: error: (Each undeclared identifier is reported only once
one.c:6: error: for each function it appears in.)

ここでこの割り当てが間違っている場合、マクロのコンテナーでどのように機能するか.上記の2つの違いは何ですか.(1つはマクロで、もう1つは通常の宣言であることはわかっていますが、マクロ展開後は両方が同じに見えます)

注:これは単純かもしれませんが、私はそれを理解することができません。

私の質問にいくつかの解決策を教えてください。

4

2 に答える 2

3

これは特別な gcc 機能、つまりブロック式を使用しています({ })。これらにより、式の中にオブジェクト定義を含めることができます。この構文の最後のステートメントは、ブロック式の値を決定します。

{ }そのため、テスト ケースの式内の追加を見逃しました。

また:

  • そのマクロには割り当てはありませんが、ローカル変数の初期化のみです
  • そこのtypeof演算子もgcc拡張です
于 2013-07-06T23:16:11.047 に答える
1

私はいくつかのポイントを得たので、この質問に私の答えを追加しています.それは他の人に役立つかもしれません.

#include <stdio.h>
int main()
{
int x = ({int k = 9;k-2;});
printf("x = %d",x);

 }

o/px = 7

Jensが上で言ったように、私は見逃しました{ }が、それに加えて、で作成されたすべての値({ })は一時的であり、式の値が評価されるとすぐに削除されるため、正しくないkの値を出力しています。

http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs

于 2013-07-08T07:11:09.453 に答える