Find the answer to your Linux question:
Results 1 to 10 of 10
I have my own declared types and I have to operate with lists of items. I wish to write a one macro, instead of using a function for each type. ...
  1. #1
    Linux Newbie
    Join Date
    Apr 2010
    Location
    Novosibirsk, Russia
    Posts
    136

    Question Append item to a list ( C macro )

    I have my own declared types and I have to operate with lists of items. I wish to write a one macro, instead of using a function for each type. It's intended to be like this:
    Code:
    #define ____append_to_list(head, item, type) \
    type* ptr; \
    for ( ptr = head; ptr->next != NULL; ptr = ptr->next ) \
    {} \
    item->prev = ptr; \
    ptr->next = item
    but when I call the macro
    Code:
    ____append_to_list(list_head, new_item, Item);
    /* list_head and new_item is a pointers of a 'Item' type */
    and try to compile it, I get gcc error

    Code:
    error: expected expression before 'Item'
    how can I use it correctly?...

  2. #2
    Just Joined!
    Join Date
    Apr 2010
    Location
    Ankara
    Posts
    10
    I tested macro in my machine. There is no problem with macro nor get compilation error, but probably your structure declaration is erroneous. Here is my code:

    typedef struct list {
    struct list* prev;
    struct list* next;
    } list;

    int main(int argc, char **argv) {
    list* head = (list *) malloc(sizeof(list));
    list* item = (list *) malloc(sizeof(list));
    ____append_to_list(head, item, list);
    return 0;
    }

  3. #3
    Linux Newbie
    Join Date
    Apr 2010
    Location
    Novosibirsk, Russia
    Posts
    136

    Post Struct definition

    Quote Originally Posted by artu View Post
    I tested macro in my machine. There is no problem with macro nor get compilation error, but probably your structure declaration is erroneous. Here is my code:
    hmm, yes, my definition differs from yours, here it is:
    Code:
    typedef struct _Item {
    /* ... */
    struct _Item *prev;
    struct _Item *next;
    } Item;
    but in other parts of code using Item type it's not a problem. Maybe it's because of compiler options?... I use GCC version 6.8 with no additional compiling or preprocessing options. I'll try to delete the underline sigil first, of course...but still interested in this phenomenon

  4. #4
    Just Joined!
    Join Date
    Apr 2010
    Location
    Ankara
    Posts
    10
    its really interesting. I got no errors with underline or without. its also should not be like that logically.
    I compiled as : gcc test.c -o test
    my gcc version: 4.4.1 (I think oldie one )

  5. #5
    Linux Newbie
    Join Date
    Apr 2010
    Location
    Novosibirsk, Russia
    Posts
    136

    Smile

    ))
    it seems that my head just has "buffer overflow" I tried to call ____list_append() but macro was defined as ____append_to_list() ... Oh, just words playing, but its price appeared high )
    there is another problem too - it's because of
    Code:
    ...
    type* ptr; \
    ...
    when I use the macro once, that's no problem. But if i call it two or more times in the same namespace (eg. in a function), compiler says that the 'ptr' is redeclared. How can I fix it?

  6. #6
    Linux Newbie
    Join Date
    Apr 2010
    Location
    Novosibirsk, Russia
    Posts
    136
    I suppose I should not declare pointer inside of macro - it seems that I need just declare a static pointer for each data type and just pass them to my macro...

  7. #7
    Just Joined! sixdrift's Avatar
    Join Date
    Jan 2007
    Location
    In and around and about Cary, NC
    Posts
    44
    Enclose the body of the macro in {} to make the "ptr" variable be local to that block. This allows you to have that variable defined multiple times locally, so you can have multiple calls to the macro. Like this:

    Code:
    #define ____append_to_list(head, item, type) \
    { \
        type* ptr; \
        for ( ptr = head; ptr->next != NULL; ptr = ptr->next ) \
        {} \
        item->prev = ptr; \
        ptr->next = item; \
    }

  8. #8
    Linux Guru Rubberman's Avatar
    Join Date
    Apr 2009
    Location
    I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
    Posts
    8,974
    Quote Originally Posted by sixdrift View Post
    Enclose the body of the macro in {} to make the "ptr" variable be local to that block. This allows you to have that variable defined multiple times locally, so you can have multiple calls to the macro. Like this:

    Code:
    #define ____append_to_list(head, item, type) \
    { \
        type* ptr; \
        for ( ptr = head; ptr->next != NULL; ptr = ptr->next ) \
        {} \
        item->prev = ptr; \
        ptr->next = item; \
    }
    Just what I was going to say. Good find sixdrift, and welcome to the forums!
    Sometimes, real fast is almost as good as real time.
    Just remember, Semper Gumbi - always be flexible!

  9. #9
    Just Joined!
    Join Date
    Apr 2010
    Location
    Ankara
    Posts
    10
    Quote Originally Posted by sixdrift View Post
    Enclose the body of the macro in {} to make the "ptr" variable be local to that block. This allows you to have that variable defined multiple times locally, so you can have multiple calls to the macro. Like this:

    Code:
    #define ____append_to_list(head, item, type) \
    { \
        type* ptr; \
        for ( ptr = head; ptr->next != NULL; ptr = ptr->next ) \
        {} \
        item->prev = ptr; \
        ptr->next = item; \
    }
    Very well sixdrift!

  10. #10
    Linux Newbie
    Join Date
    Apr 2010
    Location
    Novosibirsk, Russia
    Posts
    136
    Yeah, it works, thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...