tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Initializer and initialization macros in queue.h



I'm not sure whether this is the right place to ask but queue.h exists
under sys.

queue.h defines initializers macros (e.g. LIST_HEAD_INITIALIZER) and
initialization macros (e.g. LIST_INIT). The initializer macros have been
introduced in NetBSD. I'm not sure how what's the intended purpose of
both macro types.

If you look at the implementation both macro types generate the same
code for SLIST, LIST, SIMPLEQ, TAILQ and CIRCLEQ. Is that intended?

For static and stack allocated variables both forms seem to be correct:

#include <stddef.h>
#include <sys/queue.h>

struct entry {
    LIST_ENTRY(entry) link;
};

LIST_HEAD(head, entry);

struct head head1 = LIST_HEAD_INITIALIZER(&head1);

int main(void)
{
    struct head head2;

    LIST_INIT(&head2);

    return 0;
}

In which situation should I use which macro?

For heap allocated variables this also works but you have to use a
postfix initializer expression and therefore add the type name of the head:

#include <stddef.h>
#include <sys/queue.h>

struct entry {
    LIST_ENTRY(entry) link;
};

LIST_HEAD(head, entry);

struct s {
    struct head head;
    /* ... */
};

int main(void)
{
    struct s *s1 = NULL;
    struct s *s2 = NULL;

    /* allocate s1 and s2 */

    s1->head = (struct head) LIST_HEAD_INITIALIZER(&s1->head);
    LIST_INIT(&s2->head);

    return 0;
}

Is it guaranteed as part of the API that the initializer macros will
never include the type name in the initializer (you could get it with
typeof)?

Perhaps somebody can clarify why both macros exist, how they differ and
how they are to be used with heap-allocated and static or stack
allocated variables.

- Matthias-Christian Ott


Home | Main Index | Thread Index | Old Index