If you’re an old-timer you’ve probably written code in a large number of languages that have many different underlying philosophies. Have you used Perl? That’s a lot different from the ideas behind Algol. Interpreted Basic is so easy it brought many people into this field, but Visual Basic is an entirely different beast. My first language (after English) was Fortran, and I worked with a number of dialects and compilers. Assembly is, well, assembly. There’s not much one can say about it. C is basically assembly with massive productivity improvements. C++ is, in my opinion, rather full of complexity and dark spaces where one is wise not to tread. Java is an interesting approach to OO but garbage collection and a lack of pointers make it inappropriate for most embedded work.
C has been the lingua franca of this business for many years. Survey data shows it has most of the embedded space’s market share, and that the numbers haven’t changed much over the years.
Language use, UBM 2014 Market Survey
More modern aspirants like Python just haven’t caught on. C is going to be a major force for a very long time.
But the language is quite old and suffers from that longevity. It is also cryptic to the point of obtuseness; critics point out that C developers seem to have an aversion to typing. Most of that comes from poor habits, like using very short variable names. Any language can be abused. But comparing typical C programs to, say, Ada code and one does wonder why we seem to be so terse. And the language itself is terse.
Suppose you could wave a magic wand and change just one aspect of C. What would that be and why?
My vote is to get rid of the curly braces. All of us have suffered from bugs and compiler complaints from deeply-nested blocks of code where we get mixed up about how many closing braces are needed, and where they should be placed.
I’d prefer requiring matching begin and end blocks, with the end statement indicating which block is being closed. For instance:
for (i=0; I < max; i++) begin code; if(something) begin code; end if; end for;
There’s more typing, but any developer who can’t type fast is in the wrong profession. The upside is it is much easier to understand where blocks start and end. Sure, careful indentation tells us the same thing, but so much code today has been modified by so many people that the original engineer’s careful indenting often becomes hopelessly mangled. It can be hard to know what brace closes which block. And a misplaced brace can drive a compiler mad.
Sure, deeply nesting control structures might result in a lot of successive “end if” statements. That’s likely to be the exception rather than the rule. There’s no silver bullet that will save us, but small changes, like begin/end instead of braces, could greatly help out.
I often put an indication of which brace is closing which block in the comments. But if the language were as I’ve indicated, the compiler could point out missing and mixed-up “end” statements.
Other languages mandate and benefit from labeled end statements, with Ada being a prime example.
What about you – if you could change just one thing about C, what would it be, and why?
Jack G. Ganssle is a lecturer and consultant on embedded development issues. He conducts seminars on embedded systems and helps companies with their embedded challenges, and works as an expert witness on embedded issues. Contact him at firstname.lastname@example.org. His website is www.ganssle.com.