Thread: trying to understand sys/queue macros

  1. #1
    Registered User
    Join Date
    Jul 2013
    Posts
    23

    trying to understand sys/queue macros

    Hi,

    I am trying to understand how the macros work in sys/queue.h, but from looking at the online tutorials, I still seem to be missing something.

    I am modifying some code that exists already, and one of the changes I am making is that instead of just operating on one instance of a struct, there can be multiple instances in a list.

    For example

    Code:
    typedef struct _comm_manager{
       int something;
       // a bunch of fields
    } Comm_manager;
    The library functions then all get passed in a pointer of this type, and use it accordingly (they expect certain fields, etc).

    Applications on top use this struct also, so I am trying to make some changes to the library that don't require the applications using it to be changed.

    There are two ways I can make this a list. One is, I can add a field to the struct
    Code:
    struct _comm_manager *next;
    And the other is I can try to use the LIST_ENTRY/LIST_INIT/LIST_HEAD stuff in sys/queue.

    However, all the tutorials I've seen online require me to make another "type", and pass this type around:

    Code:
    LIST_HEAD(Comm_manager_head, Comm_manager)
    Then, this Comm_manager_head is what ends up getting passed around, requiring changes to the code.

    Is there a way to make the list without specifying a Head node of a different type? How can I use this when the struct is also typedef'd?

    I feel as I'm missing something obvious.

    Thanks!
    Gz

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,170
    Having the same struct shared between the application and library is dangerous.
    If you must do it, then at least document what each field is, and what the application can do with it - like for example how dirent is documented.

    The first thing I would suggest doing is just change the struct to
    Code:
    typedef struct _comm_manager{
       char dummy[100];  // padding for recompile test only
       struct _comm_manager *next;  // must be first
       void *nothing;  // padding for recompile test only
       // The rest of the struct is 'as is'
       int something;
       // a bunch of fields
    } Comm_manager;
    then recompile and test everything to see what (if anything) breaks.

    One likely thing to fail are explicit initialisers, for which you should declare
    Code:
    // matches (for the moment) all the dummy fields
    #define COMM_MANAGER_INIT { 0 }, NULL, NULL
    and place this in the initialiser blocks of any struct instantiations that need it.

    An alternative is to place the next pointer at the end of the struct. This has the advantage that it is less likely to break existing initialisers, and other code which assumes an internal structure, but it does mean you'll need to write your own LL handling code (which isn't that hard on a case by case basis).


    > Is there a way to make the list without specifying a Head node of a different type? How can I use this when the struct is also typedef'd?
    You could do this
    Code:
    typedef struct _comm_manager_list {
      struct _comm_manager_list *next;
      struct _comm_manager *node;
    } Comm_manager_list;
    Which is known only to the new code which specifically has to deal with lists of things.
    The advantage here is that you could declare a struct compatible with sys/queue.h, and your existing client struct is untouched.
    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.

  3. #3
    Registered User
    Join Date
    Jul 2013
    Posts
    23
    Okay, but your last solution requires defining a new struct. I'm just not sure why that's needed, as lists and queues are often "recursive" types. I guess I thought there would be a way to do it without having to specify a holder type. If not, then I am wrong and will just have to do the list myself (which isn't that hard, but sys/queue.h is convenient.)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (queue*)this)->queue::qput does not have class type
    By brack in forum C++ Programming
    Replies: 13
    Last Post: 11-11-2010, 03:41 PM
  2. Macros inside of macros
    By Chewie8 in forum C Programming
    Replies: 2
    Last Post: 02-24-2008, 03:51 AM
  3. Macros
    By silentkarma in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2006, 01:26 PM
  4. macros
    By rpc2005 in forum C Programming
    Replies: 23
    Last Post: 06-14-2005, 08:56 AM
  5. Queue and Priority Queue
    By Pamela in forum C++ Programming
    Replies: 1
    Last Post: 12-07-2001, 11:09 PM