Is C an Object Oriented Language?

C is a powerful and complex language that gives the programmer fine-grained control over memory management. However, the original question is:
can we transform the C language into an object-oriented language without modifying the compiler?
And the answer is: YES, we can.

Of course, we will not get the full power of C++. We cannot directly specify
private / public / protected members, inheritance hierarchies, or other advanced features available in C++.
What we can do is create interface-like structures and bind functions to them at runtime.

In my exploration of the C programming language and its limits, I wrote a small example that demonstrates how C can be used in a pseudo–object-oriented way.

The proposed method is to create what, in OOP terminology, would be called an interface.


typedef struct myclass
{
int value;
void (*method)(void *);
} my_class;

Immediately, the method member must be defined.
Although it is not bound to a specific implementation at compile time, the compiler still guarantees that it will only be used through this structure and assigned to instances of this “class”.

Now let’s look at a regular C function that can be attached to this pseudo-class:


void some_function(void *local_ref)
{
printf(“Your number is: %d”,
((my_class *)local_ref)->value);
}

At this point, we have a pseudo-class (the interface) and an associated method.
Now let’s see how to use it.


int _tmain(int argc, _TCHAR* argv[])
{
// Is C an object-oriented programming language?
char stop[80];

// Instance
my_class objectx;
objectx.value = 21;
objectx.method = &some_function;

// Method call
objectx.method(&objectx);

// Stop!
fgets(stop, 80, stdin);

return 0;
}

Here we clearly see the initialization of a pseudo-class instance called
objectx.
First, we assign a value to objectx.value.
Then, we assign a function pointer to
objectx.method.

This is how we create an object with both data (fields) and behavior (methods).
We can pass references to the object, reuse the same interface with different implementations, and build more complex abstractions on top of it.

To call the method, we explicitly pass a reference to the object itself, since C has no built-in concept of
this.
With the help of macros, some of this boilerplate code can be hidden, making the syntax cleaner and closer to traditional OOP.

Leave a Reply