Choosing between C and C++ Apis


My day-to-day work requires me to juggle with a large C++/C code-base. It is mostly in C++ with C apis for talking across dll boundaries.
I recently had to implement something using API which was available in both C++ and C. Contrary to my expectations, i found C apis to be easy to understand and use.

This made me think why ?

Focus : Humans can not take care of many things at same time. Mental mapping is a hard problem. Especially when we are dealing with complex systems. It is important to note that our problem in a nutshell is doing a task [ calling a function], rather than a task [class].

When you look at a C API, it is just clear. Like
      std::vector<ID_TYPE> CCloudFetchItems(ID_TYPE parent_id);  

It is simpler to compose multiple such functions together to achieve something that library
writer never anticipated.
Contrast this with looking at C++ API with some classes. Each class having some setters and getters. In short, a mini-language in itself.

However, i sincerely believe that C++ can do better. It is just the way we are mold to think
in C++ that needs a fresh air.

Lets see how a C programmer thinks different from C++ Programmer.
C code : Think that you are working in a big code-base. A new file is added by colleague :

      // my global variable
      int globalVal = 98712;

Everybody knows that global is bad. If you review this code from any C-programmer, he would
frown. Or if you are lucky, he would sit with you and find a way to remove it if it is possible.

Now lets change the code a little:
 
      // my global variable
      const int globalVal = 98712;
      // notice that this is like
      // #define globalVal 98712 // but just better.

Now i belive that many C-programmers would not mind this. If you have seen file with 20 `#defines`
in a file being `included` all over the codebase, then you know what i mean.

so, what do we learn from this ?

It is not the "globalness" but the mutation/multiflowing change that is the problem. If it changes, it is a problem. If anybody can change it, its a bigger problem.

But it looks that when c++ came, they thought that the problem is globalness. Solution is to just wrap the variable.
Put everything in a class :

      class CustomClass 
      {
        int globalVar;
        public:
        CustomClass() {}
        int GetVar() {   return globalVar; }
        void setVar(int var) { globalVar = var; }
      }; 
Now, this is the standard way of doing things in C++/Java.
Especially in java, you would have a setter/getter for every variable. This flows in the bloods of IDEs
like Eclipse that would auto-generate setters/getters for you as soon you write a variable.

so, the question is : Did we solve the problem ?

               what problem... global values.. mutations..

No it did not. The truth is that you just put a wrapper[class] around your problem.
It will not save you. It is the `state` that is the problem.

What is the fix then ?

      class CustomClass
      {
        const int globalVar;
        public:
        CustomClass(int var) : globalVar(var) {}
        int getVar() { return globalVar; }
      }; 
No setter, no mutations... i wish if i get to see many such c++ classes.

Coming back to our topic, C-APIs do not have any state..
[If they have it, it is like hell.. Start using/making C++ API then]

C-Apis are just functions.. pure i wish..

Comments