Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.std.c > #1400

Re: The C Containers Library

From jacob navia <jacob@spamsink.net>
Newsgroups comp.std.c
Subject Re: The C Containers Library
Date 2012-07-16 10:22 +0200
Organization lccwin
Message-ID <ju0j10$465$1@speranza.aioe.org> (permalink)
References <4FF9E523.6000006@spamsink.net> <e2ec6f9a-e019-4388-8293-22109594aad9@googlegroups.com> <jtvbjd$lhm$2@speranza.aioe.org> <28bf46bd-11bf-4cd1-85d4-114b65de658d@googlegroups.com>

Show all headers | View raw


Le 16/07/12 01:15, agottem@gmail.com a écrit :
> On Sunday, July 15, 2012 4:10:09 PM UTC-5, jacob navia wrote:
>> Because I decided that I would follow the same way as the C++ STL does:
>
> I think it's a mistake to try and take the STL way of doing things and shoehorn it into C.

Well, there are two possible ways of doing it:

1) The container manages the data storage
2) The user of the library manages it.

I have followed a way that allows both to be possible:

You pass the data to the container: the container manages the data 
storage requirements

You pass a pointer to the data: You manage the storage requirements. The
container just allocates space for a pointer.

Note that the second choice implies an allocator anyway since even if 
the storage requiremenets are minimal, they are still there.

Note that save/restore functions are only meaningful when the container
owns the data. When you store just a pointer to the data those
functions are useless.

I suspect the value of having a container manage element memory is 
outweighed by the flexibility and stability of the "container_of" approach.

No, as I outlined above you can pass a pointer to the data and store 
only the pointer!

>
> The container_of approach provides the following significant benefits:
>
> 1.  Functions like DequeAdd() can be error-free, avoiding needless error checking by the caller.

Mmmm, NULL pointer checks should be done anyway

>
> 2.  I can lock a mutex around DequeAdd() knowing it'll do the minimum necessary to insert my element into the container.

The library approach now is the same... You can add a mutex within the
Deque.Add function

>
> 3.  Elements can be trivially pre-allocated and added to the container without needing to bother with the complexity of an 'allocator'

Yes, but the application needs to follow all allocations now. The
complexity is not in the container but in each application.

And this is very important point. The design philosophy within the
library was to have as much complexity as possible taken AWAY from the
application into the container, assuming that debugging the container
once will be easier as debugging all those allocations and releases
done in thousands of applications.

>
> 4.  In the case of pre-allocated elements, containers can be trivially destroyed without needing to invoke a linear walk of the elements to free them.

That is why you can change the allocator to a pool allocator, that frees 
all memory at once.

>
> 5.  Adding an element to N containers won't result in N different calls to an allocator and N extra pointers to my element's data.

Yes, that is an advantage when you are inserting. But deleting becomes a 
mess!

If you want to delete an element, you have to delete it in all the
containers you have stored it in. This problem exists also when you
just store a pointer in the container.

Normally, an object is stored in a single container in most applications.

>
> 6.  The container_of method enables me to place the actual deque node anywhere within my structure.

This may be important when it comes to optimizing the arrangement of 
structures.

Storing a pointer gives you the same advantages (and incovenients).

Basically the problem with your approach is that the container's data 
structures MUST be disclosed to the user since the compiler must
know their size. Using your example:

struct my_type
{
     int my_data;
     struct deque_node my_node;
};

The structure "deque_node" must be known to be able to be inserted
into another one...

This precludes all information hiding and ties client code to the
precise structure of the container. Each new version of the container
needs a recompilation of all client code.

Using the approach of the proposed library there is NO need for 
recompilation if a new version of the library changes its internal
data structures.

jacob




Back to comp.std.c | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

The C Containers Library jacob navia <jacob@spamsink.net> - 2012-07-08 21:53 +0200
  Re: The C Containers Library agottem@gmail.com - 2012-07-15 13:13 -0700
    Re: The C Containers Library jacob navia <jacob@spamsink.net> - 2012-07-15 23:10 +0200
      Re: The C Containers Library jacob navia <jacob@spamsink.net> - 2012-07-15 23:12 +0200
      Re: The C Containers Library agottem@gmail.com - 2012-07-15 16:15 -0700
        Re: The C Containers Library jacob navia <jacob@spamsink.net> - 2012-07-16 10:22 +0200

csiph-web