最近看了libuv的源码。 读QUEUE.h有一些疑问
首先: 宏定义如下:
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 编写了这段代码。
最佳答案
首先,它们有什么区别?
你说类型是一样的,但是值是一样的吗?让我们看看我们得到了什么:
好的,关于:&((*(q))[1]))
- 取
q
,这是一个QUEUE*
。 - 取消引用
q
产生一个QUEUE
。 - 然后索引它的第二个元素,它是一个
void *
指向前一个QUEUE
- 然后获取该指针的地址(产生一个
void**
)。
我们将结果称为 &r
,其中 r
的类型为 void*
。
#define QUEUE_PREV(q) (*(QUEUE **) &r)
&r
是一个 void**
被转换为 QUEUE **
。然后它被取消引用为 QUEUE*
它是,即:Result 具有值 r
和类型 QUEUE*
。
到目前为止,还不错。这与您的尝试有何不同?
#define QUEUE_PREVR(q) ((QUEUE *) &r)
我们将 &r
(void **
)转换为 QUEUE*
。虽然这是合法的,但我们失去了一个存在的间接。 Result 的值为 &r
,类型为 QUEUE*
。类型相同,值不同。
其次:为什么“*”不起作用?
cout << (QUEUE*)&aa << endl;
cout << *(QUEUE*)&aa << endl;
在第一行中,您cout
&r
指针。指针的值因此被打印出来。在第二行中,您cout
一个QUEUE
,它是一个数组。在 sizeof
之外使用数组总是将结果转换为指向其第一个元素 (&r[0]
) 的指针。我们知道 &r == &r[0]
。
最后,
QUEUE
不应该以这种方式使用,查看 src/threadpool.c
而不是用例。
关于c++ - 对 libuv 的来源有一些疑问吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29208748/