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.

5
  • Why do you think that this global state is fine again? It's not clear from your question.
    – Telastyn
    Commented Mar 13, 2017 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." Commented Mar 13, 2017 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. Commented Mar 13, 2017 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. Commented Mar 13, 2017 at 9:01
  • @user112513312 - everyone makes that claim about all globals. Why is this a special situation?
    – Telastyn
    Commented Mar 13, 2017 at 16:48

1 Answer 1

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..

9
  • 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. Commented Mar 13, 2017 at 3:21
  • Is the "linking" performed by the caller or the library?
    – DMH
    Commented Mar 13, 2017 at 3:28
  • The "linking" itself is done by the library but is usually triggered by the caller. Commented Mar 13, 2017 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
    Commented Mar 13, 2017 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
    Commented Mar 13, 2017 at 4:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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