CMP EMBEDDED.COM

Embedded On Demand Login | Register     Welcome Guest Embedded On Demand
HOME DESIGN PRODUCTS COLUMNS E-LEARNING CONFERENCES CODE FORUMS/BLOGS NEWSLETTERS CONTACT FEATURES RSS RSS

Thread: Comments for: "Bug-killing standards for firmware coding"

 

Permlink Replies: 43 - Pages: 3 [ 1 2 3 | Next ] - Last Post: Sep 24, 2009 10:25 AM Last Post By: D_Lundin
azertyqsd

Posts: 2
Registered: 03/26/09
Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 4:57 AM
  Click to reply to this thread Reply
azertyqsd

Posts: 2
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 4:57 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Nice article.
About your rule #6: An even worse problem of the C standard is that the "char" type can be either signed or unsigned (depends on the compiler or the compiler settings).
This can lead to nasty bugs, which reproduce on one developer's machine but not the other (depending on compiler settings).
2 advices for this:
  • Always set your compiler for "unsigned" char by default.
  • Never use a "char" declaration, but always "signed char" or "unsigned char".

My $.02,
Bruno
David Brown

Posts: 12
Registered: 01/22/08
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 6:16 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
For rule #8, your example is bad - integer promotion will ensure that the uint8_t a is promoted to (int) 6, and int8_t b is promoted to (int) -9. The constant "4" is already an int (whether you like it or not), so the comparison will be done correctly as the programmer expected.

The advice is sound, however - be wary of mixing signed and unsigned numbers. Sometimes things won't work as expected, and sometimes you end up with unwanted promotions (if you add a uint16_t to a int16_t on an 8-bit processor, you'll not be pleased when the compiler follows the C standards rules and promotes then both to int32_t).
Dale Shpak

Posts: 6
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 10:42 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Great overview of good coding practices, however ...
your examples include a bug-causing practice that is related to your rule #1:
The Allman brace style should NEVER be used for languages that use braces for compound statements a semicolon for terminating statements.
During my nearly 30 years of C programming, I have debugged millions of lines of code and have encountered the following type of error many times:
while (condition);
{
/* Execute conditional code */
}
Of course, the the bug is the semicolon after the while (or if). It is very difficult to notice during code reviews. This bug is very unlikely to occur with the one-true-brace style since a ;{ would be highly visible:
while (condition);{
/* Execute conditional code */
}
It is because of the automated translation of Pascal texts to C texts and Pascal authors who switched to C that we have this dangerous practice of the Allman style.
The only valid reason to ever have a left brace on a line by itself is to limit scope.
I have converted hundreds of programmers after convincing them of the many advantages of the one-true-brace style. Once you switch, you will never go back.
Peter House

Posts: 5
Registered: 05/05/08
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 10:55 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
The matching brace style is superior to the one true brace style since it is easier for the programmer to see how the braces are matched throughout the development and maintenance of a program.

The one instance cited, elimination of ;{ does not override the deficits of this styles' deficiencies.

Block bracing makes for far more maintainable code than the one brace style as it makes the structure of your program far more visible on a line by line basis. White space in a program is your friend and having matching braces makes for easier determination of the correctness of code grouping.

We may have to agree to disagree on this one!
Dale Shpak

Posts: 6
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 10:59 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Back on my soap box:
Please don't counter my inarguable facts with the old "the left brace and right brace nicely line up with the Allman style and show me the scope of my loop". That "prettiness" argument died eons ago with the advent of context-sensitive editors that show you the matching brace.
With 1TB you get to see more of your code in the editor window, etc., etc.
Notably, the Sun Java style guide wisely uses one-true-brace.
Dale Shpak

Posts: 6
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 11:14 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Yes Peter, we will have to agree to disagree, although I strongly agree that white space is your friend. However, once you change to 1TB you will find that the structure of your code is probably more visible than it was with the Allman style, as long as you indent your code:
while (condition) {
indented code line 1
indented code line 2
}
The way to think of this is that the right brace ends the while. The indented code is obviously within the scope of the while. Since proper coding style requires that the while aways has a right brace on the same line (no single-line while statements), the structure of the code highly visible and completely unambiguous. It may take a while to get used to the 1TB mindset, but you will never go back. Trust me on this one.
Dale Shpak

Posts: 6
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 11:18 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Unfortunately, the web site didn't use my multiple spaces (vanilla html). Speaking of which: always set your editor to expand tabs into spaces so that people using other editors can see the structure of your code.
PeterLob

Posts: 14
Registered: 11/29/07
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 2:24 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
It is interesting to see how one's prior experience influences one's perception of what good coding style is. The first structured high-level language I used was PL/M-86, which -- if memory serves -- used "DO" and "END" to delimit blocks of code. I preferred to place the "DO" on a line of its own, but one of my coworkers did not. I occasionally had to review or debug his code, and I found it difficult to match a "DO" with its corresponding "END". So, when I made the transition to Pascal and later to C, I retained a preference for keeping the opening delimiter of a code block on its own line. I have debugged many lines of other people's code and have never found a bug like the one Dale describes. Such bugs are easily prevented if the coding style insists that controlling statements must always be on a separate line from the statement or code block they control, even if only an empty statement is needed.

A particularly obscure construct that seems to be part of the 1TB style is "} else {" all on one line. That not only makes it difficult to match curly braces in pairs, but also to match an "if" with its corresponding "else".

C was developed in the days when the teletype and similarly slow devices were used for input and, sometimes, also for code listings. Therefore, it includes a number of elements that allow for very terse code. Now that input devices are much faster and code listings tend not even to be generated or needed, good style should probably prohibit the use of many of those elements. For example, embedding an assignment in the condition of an "if" statement should be discouraged, as should the use of the pre- and post-increment and -decrement operators within the parameters being passed to a function or during pointer dereferencing. It takes more characters and more lines of code, but clarity is vastly improved, and many opportunities for bugs are removed.
Dale Shpak

Posts: 6
Registered: 03/26/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 2:55 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Well said, Peter. But, you do get used to 1TB, even the "} else {" all on one line. I have used both styles and have no difficulty immediately recognizing scope, nesting, or if-elseif constructs. As a matter of fact, I find it easier to match "if"s to "else"s using 1TB. With 1TB it is also easier to notice that you have the start of a new "if-elseif" in code containing several "if-elseif" blocks since the new "if" will start the line and therefore stand out from all of those "} else if {" constructs.
For the history buffs, I believe that PL/M86 used named scopes (which would help to reduce bugs):
LABL1: DO;
body
END LABL1;
The important point is that, to date, I have yet to see an example where 1TB can introduce a bug that would be prevented by the Allman style whereas I gave an example of an actual bug that I have seen several times that would be avoided by 1TB.
For mission-critical code, any practice that reduces bugs should be employed, even if it only reduces a bug having a probability of 1e-6 to a probability of 1e-9. I therefore use 1TB.
estearg

Posts: 5
Registered: 08/28/07
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 26, 2009 8:06 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
I had exactly the same experience as Dale, regarding 1TB.
And just a few days ago I downloaded sample code from TI which contained the bug Dale mentions.
1TB apart, I liked the article very much. It shows the way to go.
figurassa

Posts: 4
Registered: 03/27/09
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 27, 2009 11:25 AM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Rule #4 : Concerning the volatile keyword :

I have always tried my best to follow this rule. But recently, I have ran across some postings in the linux kernel mailing list and in other places where people were discussing the shortfalls of the volatile keyword. They advocate the use of things like memory barriers instead of volatile. From what I gathered, most of their concerns have to do with software running on more than a single CPU and I am seeing more of these devices in the embedded arena. The new C++ standard is defining to solve this problem but a lot of embedded software is still written in plain C and using older compilers.

Have any of you folks put some thought into this? What do you think? Should we be moving away from volatile? What are you using instead?

Cheers
Alex OD.

Posts: 13
Registered: 07/18/08
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 27, 2009 12:36 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Rule 5

It sure would be nice if the #if 0 ... #else ...#endif would be recognized by my IDE and be coloured so that I know it's not code. /*...*/ all goes green and comment like, so I know it's not the version I'm using today.

Hmm, there's probably a way to do it, CodeWright allowed me to set up keywords so Codewarrior must...
ErikS

Posts: 3
Registered: 10/22/07
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 27, 2009 1:56 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Rule #4, re figurassa

Not only can there be issues with multiple CPUs but a lot of C compilers mishandle volatile in single CPU architectures. There has been some discussion of this on the Safety Critical mailing list from the University of York. See the following website and paper from the University of Utah for more information:

Website: http://www.cs.utah.edu/~eeide/emsoft08/

Paper: www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf

Based on this paper an additional part to rule 4 might be stated as: All volatile accesses (read and write) shall be performed via a function call (i.e. hidden behind a function call).

Cheers!
Erik Shreve

Guest
Re: Comments for: "Bug-killing standards for firmware coding"
Posted: Mar 27, 2009 4:16 PM   in response to: azertyqsd in response to: azertyqsd
  Click to reply to this thread Reply
Many embedded target C compilers have selectable MISRA rules checks to catch such issues. Also running other static analysis tools will flag out potential bugs. For many of our projects, we have included static analysis with MISRA rules checks for clean source code check-in.

-Will

Point your RSS reader here for a feed of the latest messages in all forums




 :