Loading ...
Sorry, an error occurred while loading the content.

72496Re: Why C? If so how is the best way to have simple lists ?

Expand Messages
  • Marko Mahnič
    Jul 28, 2013
    • 0 Attachment
      > But it does not get the task done I talked about: type safe container
      > like stuff.

      I think it would be hard to create a generic type-safe container library in C. I only see two options: rewrite container manipulation code for every type of object (as is done in Vim) or define the container code as a set of preprocessor macros. In both cases a lot of code is duplicated either by the programmer or by the compiler. Also a lot of code in Vim relies on linked lists so it would be a huge and error-prone task to change all that.

      A solution compatible with the current state of Vim would be to use helpers for various containers. A helper for the linked list would look like:

      struct ListHelper
      {
      void** list_head_ptr;
      void** list_tail_ptr;
      int offset_of_next;
      int offset_of_prev;
      };

      void
      _lsthlpr_add_head(self, item)
      ListHelper* self;
      void* item;
      {
      void *pit = *self->list_head_ptr;
      *self->list_head_ptr = item;
      *(void**)((char*)item + self->offset_of_next) = pit; /* item->next = pit */
      if (self->list_tail_ptr && ! *self->list_tail_ptr)
      *self->list_tail_ptr = pit;
      }

      A list of Node structures along with it's helper would be initialized as:

      struct Node
      {
      Node* next;
      int data;
      };
      Node* my_nodes;
      ListHelper my_node_list;
      my_node_list.list_head_ptr = &my_nodes;
      my_node_list.list_tail_ptr = NULL; // we only use the forward pointer
      my_node_list.offset_of_next = offsetof(Node, next);
      my_node_list.offset_of_prev = -1; // reverse pointer doesn't exist

      Node* pnode = createNode();
      _lsthlpr_add_head(&my_node_list, pnode);

      You can still traverse the list in a type-safe way through my_nodes. The manipulation of the list through the list helper is type unsafe.

      If you feel it is absolutely necessary, a kind of run-time type safety could be achieved by adding a typeid member to the beginning of every structure that would be used in a container. The typeid for a structure would be set in a 'constructor' like createNode(). The same typeid would also be set in the helper during initialization. The helper methods would compare the value from the element to the value of the container.

      A more complex implementation of the ListHelper is in the file puls_st.c starting around line 108. It's not exactly C (without some preprocessing) but it will give you an idea.

      http://code.google.com/r/markomahnic-vim-popuplist/source/browse/src/puls_st.c?name=vim-popuplist

      A use example is in puls_st.c around line 2466 (_txmfac_init).

      http://code.google.com/r/markomahnic-vim-popuplist/source/browse/src/popuplst.c?name=vim-popuplist

      Marko

      --
      --
      You received this message from the "vim_dev" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_dev" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/groups/opt_out.
    • Show all 20 messages in this topic