原创 Best coding standard for embedded software

2016-2-5 19:08 1196 22 22 分类: 消费电子

It's not that I can’t write C per se -- it's just that I don’t write very good C (LOL). Thus, I'm currently on a quest to learn C/C++.

 

The problem is that I'm a hardware design engineer by trade. I dabble at programming -- now mostly as part of my hobby projects -- and I largely make things up as I go along. The end result is that I tend to spend an inordinate amount of time debugging my code. Sometimes the simplest thing can trip me up for ages. For example, I recently took a global int declaration that looked something like the following...

 

  int pinTiming = 7;

...and I converted it into a #define directive that looked something like the following...

  #define pinTiming 7;

This isn't the exact example, but it's close enough for you to get the idea. As you can see, I remembered to remove the equal symbol, but I forgot to strip out the semicolon at the end. I also made a few other tweaks throughout the body of the program. "This is wasy-peasy," I thought to myself... until I tried to compile the little scamp and the compiler hung up. Initially, I focused on the changes I’d made to the body of the program, so it took me ages to track this little rapscallion down.

 

One problem I have is that I've fallen into the trap of wanting my programs to look like "big boy code." In the past, I've seen code written by professional programmers that has been concise and sparing in its use of white space characters, and that has given the impression that its creator knew "what was what." On the other hand, this code has also often been cryptic and hard to read.

 

If you work for a large company, they will probably dictate the coding style you use. If you work for a smaller company, it may be more of a "free for all." And if you are an individual, you're pretty much on your own.

 

There are a lot of books on programming, but they typically focus on teaching the use of the various language operators and constructs. When it comes to coding "style," different books tend to reflect the personal preferences of the author. Take the following two versions of the same snippet of code, for example:

 

  // Version A
  for(i=1;i<10;i++){
    // Statements go here
  }

  // Version B
  for (i = 1; i < 10; i++)
  {
      // Statements go here
  }

Should there be a space after the for (Version B) or no space (Version A)? Should we use white space to separate things out between the standard parentheses (Version B) or no white space (Version A)? Should the opening squiggly bracket appear on a new line (Version B) or on the same line as the for (Version A)? Should we indent the statements forming the body code using four spaces (Version B), two spaces (Version A), or some other number of spaces?

 

Where do you go to learn this sort of thing? Well, I know where I go, because I just read the Embedded C Coding Standard by Michael Barr of the Barr Group. At only 88 pages, this isn’t a large tome, but as far as I'm concerned it's worth its weight in gold. The really good news is that it's only $9 for a PDF download and the same for a hard copy (print version) shipped by standard mail in the USA (it's $19 for a hard copy shipped anywhere else in the world).

 


(Source: BarrGroup.com)
 

The overriding reason Mike and his colleagues created this standard is to reduce the number of bugs in embedded software (a.k.a. firmware), including code added or modified later by maintainers.

 

I was chatting with Mike on the phone just a few minutes ago as I pen these words. He acknowledged that a lot of code writing comes down to personal preference, so -- when it came to creating this standard -- he and his co-contributors sat around the table arguing each point. The only criterion for selecting one style rule over another was that rule's ability to minimize potential bugs.

 

The book is divided into major sections, like Comments, White Space, Data Types, Variables, and so forth. Each of these sections is then sub-divided into a number of topics. In the case of White Space, for example, we have sub-topics of Spaces, Alignment, Blank Lines, Indentation, Tabs, and Linefeeds.

 

As an aside, the term Whitespace (paradoxically containing no spaces) is an esoteric programming language developed by Edwin Brady and Chris Morris at the University of Durham Its name is a reference to white space characters.

As it says on the Whitespace page on Wikipedia: Unlike most programming languages, which ignore or assign little meaning to most white space characters, the Whitespace interpreter ignores any non-whitespace characters. Only spaces, tabs and linefeeds have meaning. An interesting consequence of this property is that a Whitespace program can easily be contained within the whitespace characters of a program written in another language...
 

But we digress... each of the sub-sections starts off with its associated rules. These rules are followed by the reasoning behind them, any permissible exceptions, and the ways in which the rules are to be enforced.

 

Let's take the use of braces (squiggly brackets), for example. Over the years, I've bounced back and forth between having the left brace ('{') appear on the same line as its if, else, for etc. statement, or having it appear by itself on the line below the start of the block it opens. Here's what the Embedded C Coding Standard has to say:

Braces:
Rules:
  1. Braces shall always surround the blocks of code (a.k.a. compound statements) following if, else, switch, while, do, and for statements; single statements and empty statements following these keywords shall also always be surrounded by braces.
  2. Each left brace ('{') shall appear by itself on the line below the start of the block it opens, The corresponding right brace ('}') shall appear by itself in the same position the appropriate number of lines later in the file.

Reasoning: There is considerable risk associated with the presence of empty statements and single statements that are not surrounded by braces. Code constructs like this are often associated with bugs when nearby code is changed or commented out. This risk is entirely eliminated by the consistent use of braces. The placement of the left brace on the following line allows for easy visual checking for the corresponding right brace.

What can I say, except that I totally agree with all of these points? I've tried having the left brace on the same line as my if and for statements because I thought it made my code look "professional." As a result, I've spent an inordinate amount of time trying to determine which left brace was associated with which right brace.

 

I've also tried omitting braces when I had only a single statement. Once again, I did this because I thought using these braces would make professional programmers think I was a weed and a wet who didn’t have a clue. This is all the more pathetic when we come to realize that no one but myself ever looks at my code anyway. But having read this standard, I feel empowered to use braces for everything: multiple statements, single statements, and even empty statements.

 

In the case of indentation, the first rule says "Each indentation Level within a module should consist of 4 spaces" (there are additional rules that modify this first rule as necessary). The reasoning behind this reads as follows: "Fewer indentation spaces increase the risk of visual confusion, while more spaces increases the likelihood of line wraps."

 

Once again, I'm forced to agree with this. I've been using two spaces for indentation because this is what I've seen others use, but I just tried using four spaces on a block of my existing code and the result is much more readable.

One rule that almost made me squeal with delight was in regard to equivalence tests. This rule reads as follows: "When evaluating the equality or inequality of a variable with a constant value, always place the constant value on the left side of the comparison operator." What they are saying here is to use if (MAX_LOOP == loop_count) instead of using if (loop_count == MAX_LOOP). The reason for doing this is that, in the case of the former, the compiler will flag an error if we mistakenly use a single assignment "=" instead of a dual equivalency "==". I cannot tell you how many hours my implementing this rule would have saved me in the past.

 

I tell you -- I read the Embedded C Coding Standard in only one evening, but it's going to dramatically change the way I write my programs in the future. So, now all I need to do is to learn C itself (LOL). Watch this space for future developments...

文章评论0条评论)

登录后参与讨论
我要评论
0
22
关闭 站长推荐上一条 /2 下一条