Recientemente, leí la fuente de libuv. Hay algunas preguntas cuando se lee la COLA.h
En primer lugar: La macro define abajo :
typedef void *QUEUE[2];
#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0]))
#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1]))
¿Puedo redefinir el QUEUE_PREV (q) como:
#define QUEUE_PREVR(q) ((QUEUE *) &((*(q))[1]))
¿Cuál es la diferencia entre ellos?
En segundo lugar: Intento con el siguiente código:
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;
El resultado es el mismo en la consola, pero ¿por qué? Don "t el" * "funciona? Escribo este código con VS2013.
Respuestas
2 para la respuesta № 1En primer lugar, ¿cuál es la diferencia entre ellos?
¿Tienes razón al decir que el tipo es el mismo, pero es el valor? Veamos lo que tenemos:
QUEUE es typedef "d como una matriz 2 de puntero para anular
Ok, ¿qué pasa con: &((*(q))[1]))
- tomando
q
el cual es unQUEUE*
. - desreferencia
q
produciendo unQUEUE
. - a continuación, indexar su segundo elemento que es una
void *
apuntando a lo anteriorQUEUE
- luego tomar la dirección de ese puntero (produciendo un
void**
)
Llamemos al resultado &r
dónde r
es de tipo void*
.
#define QUEUE_PREV(q) (*(QUEUE **) &r)
&r
el cual es un void**
está echado a QUEUE **
. Entonces se hace referencia como la QUEUE*
es, es decir: El resultado tiene valor r
y tipo QUEUE*
.
Hasta aquí todo bien. ¿En qué se diferencia eso de tu intento?
#define QUEUE_PREVR(q) ((QUEUE *) &r)
Echamos el &r
(un void **
) a un QUEUE*
. Si bien esto es legal, perdimos una indirección que estaba presente. El resultado tiene valor &r
y tipo QUEUE*
. El tipo es el mismo, el valor no es "t".
En segundo lugar: ¿Por qué no funciona "t"?
cout << (QUEUE*)&aa << endl;
cout << *(QUEUE*)&aa << endl;
En la primera línea, tú. cout
el &r
puntero. El valor del puntero se imprime. En la segunda linea tu cout
un QUEUE
que es una matriz. usando una matriz fuera de sizeof
siempre convierte el resultado a un puntero a su primer elemento (&r[0]
). Y sabemos que &r == &r[0]
.
Finalmente,
QUEUE
no está destinado a ser usado de esa manera, echa un vistazo src/threadpool.c
en cambio para un caso de uso.