An article was brought to my attention recently. It contains an interview with Bjarne Stroustrop, of C++ fame, discussing the language to which he gave life. Aside from a few technical non sequiturs, such as referring to C++ as “the archetypal ‘high level’ computer language (that is, one that preserves the features of natural, human language)”, I found the article rather entertaining.
I found myself agreeing with most of what Mr. Stroustrup had to say. That said, I do believe there are sound reasons for many of the criticisms that C++ has endured. It’s not a matter of liking or disliking the language. There can be no doubt of it’s power and expressiveness. It is one of my favorite languages to program in; but I’m far less comfortable with it when my teammates are inexperienced in its use.
C++ gives you more than enough rope to hang, not just yourself, but your whole project. The same could probably be said of most programming languages, but the number of ways in which C++ can be abused exceeds any other widely used “high-level” programming language. As suggested in the article, most software developers just don’t seem to have what it takes to write quality code, especially in C++. Unlike Stroustrup, however, I think that the “what it takes” is not just education; but discipline. I believe there is plenty of evidence to back this opinion. For example, let’s take a look at the Python language.
Python is often used for scripting quick-n-dirty hacks, and when used in this regard I believe the resulting scripts are of superior quality to similar tools written in other languages. The reason is that, even in the absense of good commenting, the language imposes style discipline that enhances the readability of the code. For some reason, this seems to carry through to other quality attributes of the code. Perhaps the enhanced discipline imposed raises awareness in other areas. More often than not, when I’ve seen Python scripts written by a developer, the quality and design attributes of the scripts exceed those of most of the non-Python code written by the same developer. In fact, I believe this has held true in all cases except where the developer was a very experienced and disciplined individual whose other code was of the highest quality.
Sometimes Python finds use in more formal settings, for example, software test. In instances such as this, I would argue that, while it may be perfectly capable, it may be less appropriate. For unit testing, there may be no better tool; but formal software system test applications may approach or exceed the applications under test in terms of complexity. Complex software requires solid design, and in my opinion, this is where Python falls down. Good software design requires strong interfaces and strong typing; and these qualities are virtually never present in Python scripts. What I find interesting about this is that Python is perfectly capable of using strong typing and function prototypes. Type strength is stronger than that in C or C++, more like that of Java; yet I suspect that most Python users don’t even know that strong type definitions can be applied in the language. If they did, would they use them? I don’t think they would. I have never seen these capabilities put to use in any Python-based software. I am convinced that this is because developers tend to apply the minimum discipline they can get away with. Which goes back to my disagreement with Mr. Stroustrup.
The C++ language provides developers with phenominal power; but insufficient enforcement of well-founded software development principles. Education may provide developers with the information; but it can’t provide the incentive. The incentive arises only out of enforcement or experience. While the school of hard-knocks is a wonderful teacher, the tuition is quite expensive for most sponsor organizations to bear; so they rely on their most experienced developers for standards and establishment of reviews, but this does not necessarily result in a sufficient or even a consistent set of rules. Is there a better way?
Enforcing the use of language subsets is one alternative. Embedded-C++ is a “safe subset” often promoted for embedded-systems, but there is some disagreement as to precisely what a safe subset is. Other attempts in this vane have included the Ravenscar profile for Ada; and Misra standards in C. In any case, use of a language subset hardly seems the right solution to enforce code quality. Using a subset of a language simply reduces the expressiveness of the language, disallowing those features which tend to be misused or misunderstood. Shouldn’t we instead consider use of a language with the appropriate level of expressiveness?
Various languages provide features that encourage safer programming practice while simultaneaously remaining expressive and efficient; and some of these rival C++ in longevity, but none come close in popularity. Modula-3, for example, provides a powerful object-oriented paradigm, but encourages more caution by requiring that certain types of operations (e.g. pointer math) and some type conversions can only occur within modules that are declared with the keyword “UNSAFE” both in the module and its interface. I believe this encourages reduction of some of the more risk-prone operations and a more thorough analysis and review can be localized to modules which pose the greatest risk. Eiffel’s enforcement of design-by-contract has shown to be a powerful quality tool that has been adopted in varying extents by more recent offerings.
Where a language comes up short, it is always possible to make it more suitable for high-integrity purposes by attempting to outlaw its most troublesome features. This is the purpose of the MISRA standard for C, embedded-C++, and the Ada Ravenscar profile. All of these place constraints on the usages of their respective languages; and for all of their faults, they seem to have been somewhat effective in achieving their goals.
Instead of detracting from a language, you may instead add to it features that make it more rigorous and easily analyzed. This may involve adding extra keywords as the TenDRA compiler did for C and C++, or adding annotations embedded within specially marked comments, as is done with SPLint for C, SPARKAda, ESC-Java, ESC-Modula3, and a few others. This also serves as additional documentation and can be a very effective way of producing code that is more readily analyzable for correctness.
There are those who advocate that the best programming language for any project is one that is designed specifically for the domain. Yes! They suggest that if you specialize, for example, in navigation systems, that your company should use a language specifically designed to that purpose. Since such specialty languages don’t typically exist, I suppose your company will have to create it. I’ve yet to find the program manager with the ambition to tackle that concept, though I quite like the idea. I see the biggest issue with this approach in finding a suitably talented language designer, let alone one who has sufficient understanding of the domain. A poorly designed language would be no better than the existing alternatives.
As for off-the-shelf languages; Ada is probably the number one choice for high-integrity systems. In the 1980’s and early 1990’s Modula-2 also showed its mettle in these types of systems, but alas it has fallen out of favor. Modula-3 is very similar feature-wise to Ada-95, and is superior in some regards, but was never widely adopted. C and C++ are widely considered to be completely unsuitable for use in high-integrity systems, yet they are by far the most widely used languages simply because of the availability of C and C++ programmers. Java can be considered only because recent realtime implementations have become available. Java is somewhat better than C++, as the type-checking is stronger, and the purer OO model has lead to more consistent semantics. It still suffers from many of the short-comings of C++ in terms of rigor and analyzability. The annotation extensions of Java 5 may help this somewhat once compilers begin to treat them as more than syntactic sugar. Aonix is currently working on such a solution.
As a fan and advocate for automated analysis tools, I think these offer perhaps one of the best approaches for improving software; and they are useful even for the most rigorous languages. When applied at the end of a project they can find problem areas; but the true benefit comes when they are used at the beginning of development, and continuing throughout the development lifecycle. The primary reason for this is that we lazy developers will improve our coding practices just to shut the tools up! Early and consistent application of the tools serves as a conditioning mechanism. Many such tools exist for many languages. They vary greatly in their analysis techniques and issue-finding capabilities, though I have yet to find a single tool that stands-alone as a comprehensive solution.
As I said earlier, education is necessary, but the primary issue is discipline. When the language does not enforce discipline, then the discipline must be enforced by other means. The right combination of language and tool-application can dramatically improve both code quality and productivity of a software team.
Max is a father, a husband, and a man of many interests. He is also a consulting software architect with over 3 decades experience in the design and implementation of complex software. View his Linked-In profile at http://www.linkedin.com/pro/swarchitect |
Comments