Fixing C

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++)begincode;   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 . His website is .

32 thoughts on “Fixing C

  1. “Nice article Jack. I like the begin/end idea [but I have written Algol in my time …]nnWhat I would change:nSort out the static keyword. It does what it's supposed to, but that is confusing to many, as it has [at least] 2 separate meanings. It can co

    Log in to Reply
  2. “That's why you should use a IDE or syntax aware editor. Let the editor takes care of nesting properly.nnMy first language was Pascal, a begin-end style language, and I type fast. I can tell you from experience curly bracket is way better than begin-end

    Log in to Reply
  3. “How about change everything to be local and force anything you want exposed to the cruel world to be declared “global”. That would stop a lot of abuse.nI have seen a huge (really huge) structure with every variable in the whole program, and was told wh

    Log in to Reply
  4. “I would have totally revised basic types. Sure, semi-defined types made all that portability magic that brought C to its power back then. But now it has served its purpose. Now the fact that 'int' can be of arbitrary size on different platforms only makes

    Log in to Reply
  5. “Leave it alone. It does a fine job for what it is intended and then some–I've seen some beautiful c application code–and find a way to expose your real time/embedded core to something more expressive if you need to do so. Put the time in to learn the

    Log in to Reply
  6. “I was going to put that as my feature request but it can be flagged by searching your project for the regular expression:nn\s+(int|short|long|unsigned|char)\s+nn”

    Log in to Reply
  7. “I want right shift to always extend the sign bit for signed integers, instead of being implementation dependent. nAlso why are 8 bit ints promoted to “int” before any operation. Why not use the same pattern as other promotions? “

    Log in to Reply
  8. “I think that by requiring if's and for's to have {} would accomplish most of what you looking for. Also, missing an element of 'code' 'begin' and 'end' would still drive a compiler mad. I don't mind terse syntax as long as it's logical, but inadequate var

    Log in to Reply
  9. “”Minimize the use of global variables” is the sole cause of that pointer-to-structure mess you mention. This seems to be a fairly common anti-pattern. And making everything local by default would cause the perpetrator of said mess to simply prepend the

    Log in to Reply
  10. “I, too, prefer the “end” syntax, but with one-word keywords, such as “EndIf” and “Next” rather than two keywords such as “End If”. The modern IDE's make curly brace's much more manageable, but I still favor keywords.nnFor PC work, unless speed i

    Log in to Reply
  11. “Add “elseif” to eliminate problems with MISRA-C and static analyzers. Requiring braces after “else” makes for unreadable code.nnExisting code with “else if” wouldn't be affected because it would still be legal.”

    Log in to Reply
  12. “I would like to add type checking of enumerated types, as in Pascal. I believe that C treats them all as ints. There is something rather disturbing about statements that compile in C such as “Today = February”.”

    Log in to Reply
  13. “LabVIEW at 1 to 2% is interesting to note. Most of this would be on their (expensive) cRIO platform. There are extremely few who use LabVIEW to programme microcontrollers.”

    Log in to Reply
  14. “Here the changes I'd make to C:n1) { u2192 beginn2) } u2192 endn3) for (i=0; i max; i++) u2192 for i = 0 to maxn4) if (a == b) u2192 if a == bn5) Change variable declarations so that the name comes first and then the variable type (whic

    Log in to Reply
  15. “You can use an Editor or utility to auto generate some comments after braces, or you can type it yourself:nnif (something)n {n code;n } //end fornnOne important reason for the popularity of C after many years is because of large amount of c

    Log in to Reply
  16. “if i could add one feature to C language that would be nested function declaration (GCC does support this), that would save lot of efforts when declaring callback/event function, btw enclosed curly bracket is already fine, and most of C editor already co

    Log in to Reply
  17. “1. Add support for binary numbers. Still supporting Octal, but not binary, is an anachronism! I always have a file “binary.h” which defines b00000000 to b11111111 but it can't always be used.nn2. Allow “rotates” as well as shifts. All microcontrolle

    Log in to Reply
  18. “1. If functions could return multiple values, the need for passing values by reference and pointers would be reduced.nFor example: (a,b,c) = getRightTriangleSides( perimeter ); nor (passB, errorNumber) = function();n2. Support for strings with BASIC-

    Log in to Reply
  19. “While C++ can be overly complex, some aspects of it are great and clearly simplify C.nnClasses / objects, for example, are much cleaner (in my opinion) than passing pointers to structures around to C functions. “

    Log in to Reply
  20. “IMHO filthy nested bracing is a problem with your code's readability, not with the language.nI've been working with C for just something like 3 years, but one thing that comes to my mind is, as somebody has already mentioned, functions' ability to return

    Log in to Reply
  21. “After doing a great deal of Verilog coding recently, I disagree with replacing {…} with begin…end. The former sits outside of indents yet its intent is clear, while the latter introduces “noise” to the reader. Well-styled code is well spaced and has

    Log in to Reply
  22. “That's exactly what I'd suggest. The keyword to declare a variable as local to a module should be named “private” or “local”. A static variable inside a function should be declared “sticky” or something like that because this decribes the behaviour

    Log in to Reply
  23. “There are only a few things that need to be fixed.nAbolish the superfluous features: 'elseif', 'enum' and compact if's (?:) and possibly the 'do' verb.nAdd super simple form of classes from C++. Inheritance features not totally neccessary. Just enough t

    Log in to Reply
  24. “Very nice article. I had the same question a few years ago and thatninspired me to create the C2 programming language. The idea basicallynis to keep the good stuff from C and improve the things that arennot so good anymore. Also try to keep the changes

    Log in to Reply
  25. “I also started on FORTRAN (for 66, then 77 and 88). Never did work in 99.nnI have to say I prefer {} to begin/end. Begin and end just feel too much like Pascal. nnI've gotten to like C++, but you have to avoid many of the pitfalls for embedded system

    Log in to Reply
  26. “A couple of things:n1) Get rid of '//' comments.n2) Find a way to access the carry bit after a shift or overflow in arithmetic.nnI note that right shifts of negative numbers DO sign extend (as a commenter requested). The use of braces ('{' and '}')

    Log in to Reply
  27. “Good choices, except perhaps for binary notation. The number of digits required generally would reduce you to counting positions. You could group them by, say, 4 digits with separators but then you are re-inventing hex.nnI'd get rid of octal myself, I c

    Log in to Reply
  28. “- Native string data type along with native string operations n- Native support for binary data type with ability to access individual bits and bit slices.n- Multiple returns from a function”

    Log in to Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.