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
Post a Comment