Why do many functions that return structures in C, actually return pointers to structures

cdata structuresfunctionslow-levelreturn-type

What is the advantage of returning a pointer to a structure as opposed to returning the whole structure in the return statement of the function?

I am talking about functions like fopen and other low level functions but probably there are higher level functions that return pointers to structures as well.

I believe that this is more of a design choice rather than just a programming question and I am curious to know more about the advantages and disadvantages of the two methods.

One of the reasons I thought that is would be an advantage to return a pointer to a structure is to be able to tell more easily if the function failed by returning NULL pointer.

Returning a full structure that is NULL would be harder I suppose or less efficient. Is this a valid reason?

Best Answer

There are several practical reasons why functions like fopen return pointers to instead of instances of struct types:

  1. You want to hide the representation of the struct type from the user;
  2. You're allocating an object dynamically;
  3. You're referring to a single instance of an object via multiple references;

In the case of types like FILE *, it's because you don't want to expose details of the type's representation to the user - a FILE * object serves as an opaque handle, and you just pass that handle to various I/O routines (and while FILE is often implemented as a struct type, it doesn't have to be).

So, you can expose an incomplete struct type in a header somewhere:

typedef struct __some_internal_stream_implementation FILE;

While you cannot declare an instance of an incomplete type, you can declare a pointer to it. So I can create a FILE * and assign to it through fopen, freopen, etc., but I can't directly manipulate the object it points to.

It's also likely that the fopen function is allocating a FILE object dynamically, using malloc or similar. In that case, it makes sense to return a pointer.

Finally, it's possible you're storing some kind of state in a struct object, and you need to make that state available in several different places. If you returned instances of the struct type, those instances would be separate objects in memory from each other, and would eventually get out of sync. By returning a pointer to a single object, everyone's referring to the same object.