2

Which are the main advantages and disadvantages of me using opaque pointers for all my structures? I have been thinking about using this approach and here are some trivial thoughts that I have:

Trivial advantages: structure implementation is hidden, requiring who uses my modules to use only available implemented functions (creating using factories and signatures of manage/change the data in the struct).

Trivial disadvantages: structure fields cannot be accessed directly implying the need of implementing all sorts of functions to retrieve the values and only the ones the developer wants.

So the main advantage seems to be also my main disadvantage?

Is there any better approach to archive lower coupling and higher cohesion between the usage of structures in my C modules?

  • 1
    Your disadvantage (prohibiting direct access) is required for low coupling. If client code depends on the contents and layout of your structure, it's coupled to it. Note however that writing accessors for every member is also a bad sign, because the client code can depend on each indirectly-accessed member existing. If the client really needs all that information, maybe it should be inside your high-cohesion module rather than outside, or maybe you need to re-think your interface. – Useless Mar 8 '17 at 17:13
  • 4
    Hiding structs behind opaque pointers is how you implement Abstract Data Types in C. So, your question basically boils down to "Advantages and Disadvantages of Data Abstraction". – Jörg W Mittag Mar 8 '17 at 17:22
  • So the fact of abusing in the creation of a high number of accessors would reduce performance compared to direct access of a public structure right? – Pedro Freitas Mar 8 '17 at 17:40
3

One major disadvantage: using an opaque pointer prevents you from allocating the structures from the stack. Thus, if you have one function call where you need a structure for the duration of the call but don't need it after the function has returned, you are still forced to use malloc() for the structure.

Don't do that! malloc() is much, much slower than stack allocation. Not only that, but also malloc() is prone to memory leaks. If you instead define the structure in the header file, you can allocate the structure from the stack for the example case.

Of course, having the structure in the header file allows misusing it by breaking the abstraction. So, it is your responsibility to define functions operating on the structure and make sure that everybody consistently uses only those functions and not direct member access.

For this reason, I almost always define structures in header files. I also define functions operating on the structure, initializer/finalizer functions, and a STRUCTURE_INIT preprocessor macro that can be used instead of a function call to initialize the structure (if feasible).

Also, if the structure is defined in a header file, you can use static inline functions. They are much faster than real function calls, while not having the downsides of preprocessor macros.

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.