Archive for June, 2018

Proposed Rule Changes for Embedded C Coding Standard

Wednesday, June 20th, 2018 Michael Barr

My book Embedded C Coding Standard began as an internal coding standard of a consulting company and was first published in 2008 by that company (Netrino). In 2013, the book’s cover was given a new look and the standard became known as “Barr Group‘s Embedded C Coding Standard“. A 2018 update to the book will be released soon and this will be the first time the substance of the standard has changed in over a decade.

The primary motivation for making changes is to better harmonize the rules with the MISRA-C Guidelines. The older Barr Group standard made reference to MISRA C:2004, which was superseded by MISRA C:2012. The few known direct conflicts between BARR-C:2013 and MISRA C (stemming from our earlier embrace of ISO C99) were effectively eliminated with their 2012 update. But we wanted to do more than just remove those noted conflicts and push even further in our embrace of harmonization.

In a sentence, MISRA C is a safer subset of the C language plus a set guidelines for using what is left of the language more safely. In about as many words, BARR-C is a style guide for the C language that reduces the number of defects introduced during the coding phase by increasing readability and portability. It turns out there is quite a bit of value in combining rules from both standards. For example, MISRA’s guidelines do not provide stylistic advice and applying BARR-C’s stylistic rules to the C subset further increases safety.

The rest of this post is a preview of the specific rule changes and additions we will make in BARR-C:2013. (Omitted from this list are rules reworded simply for greater clarity.)

Rule 1.1.d (new)

The following rule will be added:

Preprocessor directive #define shall not be used to alter or rename any keyword or other aspect of the programming language.

Rule 1.6.b (new)

The following rule will be added:

Conversion from a pointer to void to a pointer to another type shall be cast.

Rule 1.7.c (change)

The earlier rule:

The goto keyword shall not be used.

will be replaced with:

It is a preferred practice to avoid all use of the goto keyword. If goto is used it shall only jump to a label declared later and in the same or an enclosing block.

This is being done so that the BARR-C standard does not restrict uses of goto that are permissible under MISRA C.

Rule 1.7.d (change)

The earlier rule:

The continue keyword shall not be used.

will be replaced with:

It is a preferred practice to avoid all use of the continue keyword.

This is being done so that the BARR-C standard does not restrict uses of continue that are permissible under MISRA C.

Rule 1.7.e (eliminated)

There will no longer be any restriction on the use of the break keyword. This is being done so that the BARR-C standard does not restrict uses of break that are permissible under MISRA C.

Rule 4.2.d (change)

The earlier rule:

No header file shall contain a #include statement.

will be replaced with:

No public header file shall contain a #include of any private header file.

This is being done because apparently no one (other than me) actually valued the old rule. 🙂

Rule 5.1.c (new)

The following rule will be added:

The name of all public data types shall be prefixed with their module name and an underscore.

Rule 5.4.b.v (new)

The following rule will be added:

Always invoke the isfinite() macro to check that prior calculations have resulted in neither infinity nor NaN.

Rule 5.6.a (new)

The following rule will be added:

Boolean variables shall be declared as type bool.

Rule 5.6.b (new)

The following rule will be added:

Non-Boolean values shall be converted to Boolean via use of relational operators (e.g., < or !=), not via casts.

Rule 6.2.c (changed)

The earlier rule:

All functions shall have just one exit point and it shall be at the bottom of the function. That is, the keyword return shall appear a maximum of once.

will be replaced with:

It is a preferred practice that all functions shall have just one exit point and it shall be via a return at the bottom of the function.

Rule 6.3.b.iv (new)

The following rule will be added:

Never include a transfer of control (e.g., return keyword).

Rule 7.1.n (new)

The following rule will be added:

The names of all variables representing non-pointer handles for objects, e.g., file handles, shall begin with the letter ‘h’.

Rule 7.1.o (new)

The following rule will be added:

In the case of a variable name requiring multiple of the above prefixes, the order of their inclusion before the first underscore shall be [g][p|pp][b|h].

Rule 7.2.c (new)

The following rule will be added:

If project- or file-global variables are used, their definitions shall be grouped together and placed at the top of a source code file.

Rule 7.2.d (new)

The following rule will be added:

Any pointer variable lacking an initial address shall be initialized to NULL.

Rule 8.2.a (changed)

The earlier rule:

The shortest (measured in lines of code) of the if and else if clauses should be placed first.

will be replaced with:

It is a preferred practice that the shortest (measured in lines of code) of the if and else if clauses should be placed first.

Rule 8.3.c (new)

The following rule will be added:

Any case designed to fall through to the next shall be commented to clearly explain the absence of the corresponding break.

Rule 8.5.b (new)

The following rule will be added:

The C Standard Library functions abort(), exit(), and setjmp()/longjmp() shall not be used.

If you have questions about any of these draft changes or suggestions for better or other changes, please comment below.

C’s goto Keyword: Should we Use It or Lose It?

Wednesday, June 6th, 2018 Michael Barr

In the 2008 and 2013 editions of my bug-killing Embedded C Coding Standard, I included this rule:

Rule 1.7.c. The goto keyword shall not be used.

Despite this coding standard being followed by about 1 in 8 professional embedded systems designers, none of us at Barr Group have heard any complaints that this rule is too strict. (Instead we hear lots of praise for our unique focus on reducing intra-team stylistic arguments by favoring above all else C coding rules that prevent bugs.)

However, there exist other coding standards with a more relaxed take on goto. I’ve thus been revisiting this (and related) rules for an updated 2018 edition of the BARR-C standard.

Specifically, I note that the current (2012) version of the MISRA-C Guidelines for the Use of the C Programming Language in Critical Systems merely advises against the use of goto:

Rule 15.1 (Advisory): The goto statement should not be used

though at least the use of goto is required to be appropriately narrowed:

Rule 15.2 (Required): The goto statement shall jump to a label declared later in the same function

Rule 15.3 (Required): Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement

Generally speaking, the rules of the MISRA-C:2012 standard are either the same as or stricter than those in my BARR-C standard. In addition to overlaps, they have more and stricter coding rules and we add stylistic advice. It is precisely because MISRA-C’s rules are stricter and only BARR-C includes stylistic rules that these two most popular embedded programming standards frequently and easily combined.

Which all leads to the key question:

Should the 2018 update to BARR-C relax the prior ban on all use of goto?

According to the authors of the C programming language, “Formally, [the goto keyword is] never necessary” as it is “almost always easy to write code without it”. They go on to recommend that goto “be used rarely, if at all.”

Having, in recent days, reviewed the arguments for and against goto across more than a dozen C programming books as well as other C/C++ coding standards and computer science papers, I believe there is just one best bug-killing argument for each side of this rule. And I’ll have to decide between them this week to keep the new edition on track for a June release.

Allow goto: For Better Exception Handling

There seems to be universal agreement that goto should never be used to branch UP to an earlier point in a function. Likewise, branching INTO a deeper level of nesting is a universal no-no.

However, branching DOWN in the function and OUT to an outer level of nesting are often described as powerful uses of the goto keyword. For example, a single goto statement can be used to escape from two or more levels of nesting. And this is not a behavior that can be done with a single break or continue. (To accomplish the same behavior without using goto, one could, e.g., set a flag variable in the inner block and check it in each outer block.)

Given this, the processing of exceptional conditions detected inside nested blocks is a potentially valuable application of goto that could be implemented in a manner compliant with the three MISRA-C:2012 rules quoted above. Such a jump could even proceed from two or more points in a function to a common block of error recovery code.

Because good exception handling is a property of higher reliabilty software and is therefore a potential bug killer, I believe I must consider relaxing Rule 1.7.c in BARR-C:2018 to permit this specific use of goto. A second advantage of relaxing the rule would be increasing the ease of combining rules from MISRA-C with those from BARR-C (and vice versa), which is a primary driver for the 2018 update.

Ban goto: Because It’s Even Riskier in C++

As you are likely aware, there are lots of authors who opine that use of goto “decreases readability” and/or “increases potential for bugs”. And none other than Dijkstra (50 years ago now!) declared that the “quality of programmers is [inversely proportional to their number] of goto statements”.

But–even if all true–none of these assertions is a winning argument for banning the use of goto altogether vs. the above “exception handling exception” suggested by the above.

The best bug-killing argument I have heard for continued use of the current Rule 1.7.c is that the constructors and destructors of C++ create a new hazard for goto statements. That is, if a goto jumps over a line of code on which an object would have been constructed or destructed then that step would never occur. This could, for example, lead to a very subtle and difficult type of bug to detect–such as a memory leak.

Given that C++ is a programming language intentionally backward compatible with legacy C code and that elsewhere in BARR-C there is, e.g., a rule that variables (which could be objects) should be declared as close as possible to their scope of use, relaxing the existing ban on all use of goto could forseeably create new hazards for the followers of the coding standard who later migrate to C++. Indeed, we already have many programmers following our C coding rules while crafting C++ programs.

So what do you think? What relevant experiences can bring to bear on this issue in the comments area below? Should I relax the ban on goto or maintain it? Are there any better (bug-killing) arguments for or against goto?