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

好的,那么:&((*(q))[1]))

  • 采取q哪一个QUEUE*
  • 取消引用q产生一个QUEUE.
  • 然后索引它的第二个元素,它是void *指向前一个的QUEUE
  • 然后获取该指针的地址(产生 a void**)。

让我们将结果称为&rwherer类型void*


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

&r这是 avoid**被强制转换为QUEUE **。然后按原样取消引用QUEUE*,即:Result 具有 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指针。指针的值就这样打印出来了。在第二行中,你coutQUEUE一个数组。使用外部数组sizeof总是将结果转换为指向其第一个元素的指针 ( &r[0])。我们知道这一点&r == &r[0]

最后,

QUEUE不打算以这种方式使用,请查看src/threadpool.c用例。

于 2015-03-29T17:46:25.600 回答