Readability Advantages of C over C++

C++ is a language that was created to improve some of the features and use cases of the C language, in order to make it easier to use for application development (instead of system programming, the main area dominated by C). One of the perceived problems in C is the lack of support for object oriented features that are so common on the development of desktop applications. For example, C lacks the concept of a type that encapsulates code and data. While it is possible to program in an object oriented style in C, it is somewhat cumbersome to use such a style.

In order to make C easier to use, C++ designers added a number of features that would be more appealing to programmers. Inheritance was one of them, used to support object oriented features. Overridden methods were also added to improve object oriented programs.

C++ also added some features that can be considered syntactic sugar for already supported operations. For example, operators can be overloaded, so that many math operations, and even punctuation such as “,” can be overloaded by programmers. Normal functions can also be overloaded, by providing versions that differ on the number and type of arguments.

Later on, C++ added templates to fix a problem with the language’s type system. With templates, it is possible to instantiate a class based on one or more types. This allows for the creation of containers, such as the ones found in the STL. Vectors, maps, and multimaps can all be created by adding a type as a parameter for template instantiation.

Consequences

Although C++ designers succeeded in creating a language with support for most object oriented features, there are a lot of unintended consequences of the way many of these features were introduced.

Unlike C, in C++ it is difficult to understand, by just looking at the code being written, what will be really executed at run time. This has always been a problem with object oriented languages due to polymorphism. However, the problems have been compounded by the liberal use of overloading features in C++ programs.

Clearly, in C it is possible to write convoluted programs (especially if one wants to use the preprocessor). However, in general one just has variable declarations, function declarations, function calls, and simple expressions (such as mathematical and logical expressions). Maybe the results of a function call may not be completely understood by the programmer, but from the syntactical point of view it is easy to figure out what is going on in the program.

And, to put it clearly, the problem is not that the function or class is doing something we don’t know. The problem is mostly in trying to figure out what is happening in a given line of code. In C is very easy to figure out what is being called (up to macros): just read the manual for the functions being used and you will have a good idea of what is being executed.

In C++, on the other hand, a large number of things can be happening in a single line: an overloaded operator, a type conversion, a template instantiation, an overridden function in one of a dozen of classes, a constructor called in some part of the hierarchy, in some namespace… Who knows? You have to be smart enough to figure out what is going on in each of these cases. As your code base grows, this makes it increasingly hard to understand what is going on.

And this is not even considering issues such as exceptions, which are a huge liability, since you have to check that they will leave your program in a reasonable state at each part of your code.

Conclusion

While C++ provides a lot of helpful features for application programming, these features have a cost. It becomes increasingly difficult to understand what is going on in each line of code, unless the developers are very disciplined.

This also shows a little of the myth surrounding the idea that C++ is better than C for large code bases. While C++ has some features that might be helpful, in general the bigger the C++ code base the harder it is to understand due to these issues.

This is true even for automated tools. It is very difficult to create automatic tools to parse and change C++ (for example, to perform refactoring). In comparison, C is much easier to understand, and one can do a lot with tools such as ctags. It is not a surprise that large scale projects such as the Linux kernel use C without any problem.

Similar Posts:

About the Author

Carlos Oliveira holds a PhD in Systems Engineering and Optimization from University of Florida. He works as a software engineer, with more than 10 years of experience in developing high performance, commercial and scientific applications in C++, Java, and Objective-C. His most Recent Book is Practical C++ Financial Programming.

6 Responses to “Readability Advantages of C over C++”

  1. haters gonna hate

    By lauoeuhnts on May 31, 2011

  2. I totally agree to this article.

    @lauoeuhnts, your reaction is ridiculous.

    By Plumsi on May 31, 2011

  3. 100% agreed with this article. C++ simply requires too much context to understand any given line of code. That being said, wise practitioners of C++ tend to use subsets of what is clearly an over-designed language. For example:
    1. No operator overloading other than with streams.
    – Arithmetic operators for complex numbers, matrices, and strings (+ for concatenation) being the only exceptions
    2. Cautious use of Boost some of Boost is quite over-designed as well, because they tried to make it so flexible.
    3. No template meta-programming unless it is a clearly obvious thing, like compile-time factorials.
    4. Composition over inheritance. Inheritance can be abused to the point of making code unreadable. In fact, this last point is perhaps the most important and it is one of the chief observations of this article — overloaded functions is one thing, but excessive use of virtual functions makes it near impossible to see what’s going on when a developer reads code.

    I do program in C++ every day, and the language does have some advantages over C. More often than not it is abused by developers who are trying to be clever, and the end result is code that is difficult to debug, maintain, and extend.

    By John on May 31, 2011

  4. i second lauoeuhnts. go back to java. operator overloading is useful in many different contexts. people who can’t cope with operator overloading should stop whining about it and ask someone with a bigger brain to look at the code.

    @John … every one ought to know composition is more powerful that inheritance ! And I agree with your second point. I personally waiting for someone come up with looking for a boost<easy<on<your>>>

    By anonymous on May 31, 2011

  5. Virtual calls in C++ and calls via manually created vtable in C are equally difficult to inspect. (At least we have tools for C++ case.)

    If two overloaded methods do something significantly different then complain to their author.

    Overloaded operators and type conversions are expected to be used sparingly. They should be used for operations that are not usually interesting (e.g. converting CWnd to HWND, converting CFont to HFONT).

    Exceptions: you have to make sure they will leave your program in a reasonable state even if you use returning error codes. Exceptions do not make it more difficult, actually they would need even less code.

    By Petr on Sep 6, 2011

  6. Simply put, I never want to learn another language other than C, is because I want to *only* develop an application’s logic for a platform, systems/web etc.

    I know C and it helps me do it well. End of story.

    By Vijay Kanta on Apr 23, 2012

Sorry, comments for this entry are closed at this time.