2

I have a library in C where the API uses "objects" to interact with the application. These "objects" are opaque pointers that are created, destroyed, and modified via API calls.

These "objects" do not exist in a hierarchy and their lifetimes are loosely managed. As a result, the library has to keep pools of these objects and track of which ones are being used and which ones aren't. This requires that the library has some sort of state for managing these pools.

My current solution use a global state to manage them, like so:

initializeLibrary();
Object *obj = createObject();
//Do something with obj
destroyObject(obj);
terminateLibrary();

However, it's entirely possible to make the library not rely on global state:

Instance *instance = initializeLibrary();
Object *obj = createObject(instance);
//Do something with obj
destroyObject(obj);
terminateLibrary(instance);

My reason for using a global state is that it's easier to read the code when I'm not passing around an instance variable everywhere. Generally the reason given for why global states are bad is that it results in unpredictable behavior, but I don't think that applies here.

My question is whether or not my use of global state is a bad design choice.

  • Why do you think that this global state is fine again? It's not clear from your question. – Telastyn Mar 13 '17 at 1:51
  • @Telastyn "My reason for using a global state is that it's easier to read the code when I'm not passing around an instance variable everywhere." – user112513312 Mar 13 '17 at 3:09
  • There isn't enough context about what this library does and how its used to have anything close to a worthwhile insight. – whatsisname Mar 13 '17 at 4:10
  • 1
    I'd like to point out that your global state very much changes behavior. If I call terminateLibrary, the other functions presumably won't work anymore. – Sebastian Redl Mar 13 '17 at 9:01
  • @user112513312 - everyone makes that claim about all globals. Why is this a special situation? – Telastyn Mar 13 '17 at 16:48
4

Your library needs to keep track which objects are being used why?

Shouldn't it be the responsibility of the owner of those objects to know that information unless there is some context to all of them?

If the objects don't depend on each other then the library shouldn't need to keep track of which ones are being used, that's their owners job.

If there is indeed some context then simply provide that context to the outside world and require its use on the API calls..

  • Sorry if my question was not clear. The objects do depend on each other, but they don't exist in a strict hierarchy. The names for the function are a bit misleading. If two objects are "linked" and one is destroyed, it will persist until the other is destroyed as well. I know this sounds like a bad design but that's something unrelated to the question. – user112513312 Mar 13 '17 at 3:21
  • Is the "linking" performed by the caller or the library? – DMH Mar 13 '17 at 3:28
  • The "linking" itself is done by the library but is usually triggered by the caller. – user112513312 Mar 13 '17 at 3:36
  • I believe that when the linking is triggered you should returned some representation of this linking between the objects and have the caller operate on it, otherwise it's just extremely difficult to keep track of what object is still valid or not. – DMH Mar 13 '17 at 3:43
  • If that's the case then when someone tries to do something nonsensical return an error indicating the object is still in use. Either way moving this global state to a specific instance that is passed around would be best (especially as it'll force you to design the system without expecting the global state). – DMH Mar 13 '17 at 4:10

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.