Monday, September 27, 2010

C vs C++, The Ultimate Showdown

I've been having ongoing debates with my friend _waker_, about C vs. C++, and if they had a fight, who would kick whose ass?

I will make a disclaimer that I am very much a fan of C++ and object oriented programming, and my experience in C is limited to a few experimental programs in highschool, after which I said "no thanks". Nothing wrong with C, but C++ is just so much cooler, and would kick C's ass any time of day if they met on the street.

However, I have a lot of respect for waker and other C lovers out there, and a lot of the points they make are very valid, so let's duke it out right here, and pretend C has just met C++ on a street corner, and they both rolled up their sleeves for The Ultimate Showdown. I will attempt to summarize the arguments of the other side to the best of my ability.

Arguments for C (courtesy waker) Counter-arguments for C++
C code is easier to read, and maintain                     I guess this depends on the context, but I've certainly seen some nasty C code, especially involving unnecessary pointer arithmetic, unnecessary linked lists, problems due to most members being "public", too much communication via global variables, functions with too many arguments, etc.
C is closer to the lower level machine architecture and C code tends to be more optimal                                                                                                                                           True, but optimization is not often the primary factor in software development. This day and age, performance is an important factor only in some areas, but readability and maintainability have a much greater impact on major software projects. You have to balance the cost of making the project with the speed you get out of it. 

Arguments for C++ Counter-arguments for C
There are a lot more large scale projects written in C++ than in C, and for good reason. Huge software bases are a lot easier to write and maintain in an object oriented language. There's fewer lines of code to write, and a lot more tools available to make modular design There are in fact very large code bases maintained in C, especially in the open source community, such as the Linux kernel. Besides the choice of language in a company is often driven by considerations other than performance.                                                                                                                                                                                                            
C++ code provides a lot of seemingly useful tools, such as virtual functions, templates, inheritance, data hiding Most of the language features end up being misused, and the typical traps a C++ project will get itself into are far worse than those we can create with C. When the only things you have to worry about in C is functions and structs, life becomes a lot easier in some ways. There's a lot fewer knots your program can tie itself into in C, and when it does, they're easier to unravel.                  

Perhaps the most convincing and intuitively appealing analogy for the inferiority of object-oriented design is the following:
"C is like working with dough or clay and building a structure that's in constant flux, while C++ attempts to build the same buliding out of bricks of different size".

Back in the world of software, this means that C++ attempts to impose structure on parts of the program prematurely, because the parts in fact depend on the whole. We use classes and class hierarchies as building blocks, and then we find ourselves continuously tearing those building blocks down, as we find them unsuitable for the task at hand. C++ and other object oriented languages are thus based on the wrong assumption that we can build large flexible applications out of stable building blocks. What we end up discovering again and again is that the building blocks we originally constructed are not quite good enough for the task, and we need to go back and rebuild the foundation (refactor). In C, the building blocks (functions and structs) are much smaller, and thus it has a lot fewer problems being fitted to the task of maintaining large software projects, which are constantly in flux. 

This, I believe is a very powerful point, and does underline the main issue of object oriented languages, and maintenance of large projects written in them. This perhaps is even the reason I started writing this blog, seeing the pitfalls of object oriented design, and the way object oriented language constructs are misused. However, I do believe that the tools provided by C++ are very powerful, and can do a lot more good if used right. As for the analogy of building the building out of clay, perhaps the art of refactoring is precisely in how to change the bricks together with the building, the bricks need to be continuously revisited as the shape of the building becomes clearer.

    No comments:

    Post a Comment