Code:
int
dequeue_shared_queue(struct shared_queue *q, void **elem)
{
pthread_mutex_lock(&(q->access));
*elem = fifoQueueDequeue(q->queue);
pthread_mutex_unlock(&(q->access));
}
struct packet *
dequeue_packet(struct channel *chnl)
{
int ret;
struct packet *p = NULL;
// void *p = NULL;
ret = dequeue_shared_queue(chnl->packet_queue, (void **)&p);
...
return p;
}
I use gcc 3.4.4 on Solaris 9 and I got a warning: "dereferencing type-punned pointer will break strict-aliasing rules". By declaring p as "void *" rather than "struct packet *", the warning disappears amd there is no other warning.
I googled "dereferencing type-punned pointer will break strict-aliasing rules" and based on the search results I read, it appears that gcc issues the warning because the compiler does not like the fact that the same 'memory location' is accessed by both a void * and a struct packet *, correct me if i am wrong. (Well, I am not eaxctly sure what the 'memory location' is at issue here.)
There was an old post http://cboard.cprogramming.com/showthread.php?t=91958 that mentions a function that, like dequeue_shared_queue() above, also has a parameter of the type void **. And the poster also passes a '(void **)&data' to it. So I guess it is okay (or even common) to have a void ** as a parameter. But that post does not mention any compiler warning like mine.
Now, my questions are:
1. Would the code in that old post also generate a similar warning? If not, why not?
2. If I do the following, then there is no warning:
Code:
struct packet *
dequeue_packet(struct receiving_channel *chnl)
{
int ret;
struct packet *q = NULL;
void *p = NULL;
ret = dequeue_shared_queue(chnl->packet_queue, (void **)&p);
q = p;
...
return q;
}
Why?
Could someone kindly explain all these void ** and casting business to me (preferably, in relation to the "strict aliaing rules")? Other than introducing an additional void pointer like in the last piece of code above, is there any way to eliminate the warning?