Thread: pointer to pointer to void - dereferencing type-punned pointer, strict-aliasing rule

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    98

    pointer to pointer to void - dereferencing type-punned pointer, strict-aliasing rule

    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?
    Last edited by hzmonte; 08-27-2007 at 12:01 AM.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Why not make the type what it should have been in the first place:

    Quote Originally Posted by hzmonte View Post
    Code:
    int
    dequeue_shared_queue(struct shared_queue *q, struct packet **elem)

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    There is an implicit assumption in the first version of your code that all pointers are represented in the same way.

    > *elem = fifoQueueDequeue(q->queue);
    If a void* pointer were larger than a struct packet * pointer say, then this assignment would end up trashing some memory. Even if it fits, there's no guarantee of equal representation.

    Given int a, b;
    It's analogous to doing memcpy(&b, &a, sizeof a) rather than b = a;
    Now imagine that b is a short rather than an int. You'd expect assignment to do the right thing, but the memcpy() approach is broken.

    Remember that void* (and only void*) is special in that it is a kind of union of all possible pointer types (to permit the void* to anytype* and back again assignments).

    A void** pointer behaves like every other kind of pointer. The fact that you needed to use a void** cast should be alerting you to the possibility of trouble.

    > is there any way to eliminate the warning?
    Either make it type-correct as brewbuck suggests, or use the extra assignment route you proposed.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jul 2005
    Posts
    98
    Quote Originally Posted by Salem View Post
    There is an implicit assumption in the first version of your code that all pointers are represented in the same way.

    > *elem = fifoQueueDequeue(q->queue);
    If a void* pointer were larger than a struct packet * pointer say, then this assignment would end up trashing some memory. Even if it fits, there's no guarantee of equal representation.
    .
    What do you mean by the representation of a pointer? Don't all pointers have the same size? And besides size, what are there in the representtaion?
    Quote Originally Posted by Salem View Post
    > is there any way to eliminate the warning?
    Either make it type-correct as brewbuck suggests, or use the extra assignment route you proposed.
    I do not like what brewbuck suggests because that dequeue function may be used by modules whose data is not packet but some other things.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Don't all pointers have the same size?
    The C standard doesn't say that they should, doesn't rely on them being the same, and some real machines have had different pointer sizes.
    http://www.c-faq.com/null/machexamp.html

    I guess you need to use your 2nd example then, the one with the extra assignment.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inserting a swf file in a windows application
    By face_master in forum Windows Programming
    Replies: 12
    Last Post: 05-03-2009, 11:29 AM
  2. can someone help me with these errors please code included
    By geekrockergal in forum C Programming
    Replies: 7
    Last Post: 02-10-2009, 02:20 PM
  3. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  4. Replies: 3
    Last Post: 05-13-2007, 08:55 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM