2

I've written a couple of libraries since beginning to use C again last year. One thing that still needs addressing in both of these is the correct use of array-based lists - hereafter, ArrayLists.

At present I tend to do one-off array allocations (usually static allocation) based on library constants (defines) that may be tweaked by the user before compile. Usually I use arrays of pointers or small values, so memory lost by allocating excessive sizes is of little concern.

This approach is fine for many cases but not for all. For example, right now I need to implement the Observer pattern as part of one these libraries, and it seems wise to have a dynamically-sized array for the subscriber lists stored on the publisher. So it seems the right time to set up ArrayLists for all cases, replacing my old fixed-size arrays for the most part.

My question is about the details of this as it pertains to general-use libraries. There are many ArrayList implementations out there and it would be naive of me to assume that mine is any better than those others. I do not want to force my implementation on anyone; or, put another way, just because you choose to use my library does not mean I want you to use my naive ArrayList. Not only that, but in many cases, if my library is used in a given project, it would seem natural to be using your own ArrayList implementation across all code in that project, rather than mine for certain stuff, and yours for other stuff - it should be uniform.

Here's how I think I should tackle this in C, using publisher/subscriber as the example:

  • In the header, declare interface functions to wrap different implementations, so e.g. publisher_add_subscriber() would wrap an add() call for some ArrayList, could be yours, mine, or someone else's: point being that different implementations could be swapped in/out;
  • ensure that any functions thus implemented using my default ArrayList implementation are not part of the library's main source file, but rather are kept in a separate source file so that it is trivial to reimplement them.

Are there any obvious problems with this assumed course? Suggestions or alternatives?

P.S. FWIW, my C is very object-oriented in nature; perhaps this will better inform your responses.

P.P.S. One obvious answer might appear to be, "Your ArrayList is an implementation detail and so should anyway be hidden behind a suitably opaque interface, thus making it irrelevant." There is some truth to this, except for two things: (1) C exposes all data, and for this reason I like having access to similar data structures across the board when choosing to access internals; (2) one could choose to swap in another ArrayList implementation for performance reasons.

  • Put a comment in <arraylist.h> to the effect of: /* Instead of linking arraylist.c, you can define these as wrappers to your favorite implementation? */ – Davislor Sep 24 '15 at 22:05
  • In C++, which you aren’t using, you could do what the STL does and duck-type. If it looks like an arraylist and quacks like an arraylist, at least in a template, it's an arraylist. – Davislor Sep 24 '15 at 22:08
  • From the relative silence... is this level of abstraction not typical in C? – Engineer Sep 25 '15 at 13:01
0

I decided to hardcode a fast, robust, third-party arraylist solution in for now. I may in future go with the approach outlined in my question. Ultimately though, if all ArrayList accesses are hidden behind an opaque interface, it should not matter too much which implementation is chosen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.