If you’re working in a collaborative environment or if your projects are shared between different teams or companies, having a well defined coding standard can be useful to make sure that your code is easily understandable and maintainable between developers and down the road.
Aside from cosmetic issues like clear and consistent naming conventions (helpful as that is when debugging), a good set of coding standards also includes a lot of hard-won wisdom on what you should or shouldn’t do for reliability reasons as well.
While certain development platforms like C# (.Net) tend to have a single widely accepted ‘coding standard’ (the “IDesign C# Coding Standard” probably being the best and most widely adopted for that platform), things are a bit less homogonous for C (more broadly) or embedded C (specifically), and a few different ‘styles’ exist (K&R C, etc.).
A lot of this comes down to personal preference, but the following resources may be useful if you’re trying to improve your own coding, particularly for embedded systems where you have some unique safety and practical concerns.
Software Development with C – Coding Guidelines
A summary of current coding standards from Alexander Neundorf at the Technische Universität Kaiserslautern, this presentations has a good summary of C Coding Standards if you’d like a more in-depth description of why having a coding standard is important and what some of your options are.
MISRA is the “Motor Industry Software Reliability Association”, and amongst many other publications they have published, their “Guidelines for the Use of the C Language in Critical Systems” has been widely adopted both inside and outside of the automotive industry. As a ‘standard’, it’s quite restrictive, but this goes with the nature of safety-critical systems such as automotive, medical devices, etc. This particular standard sets the bar pretty high, but it also gives you a high confidence in the portability of your code and can help avoid a wide variety of common pitfalls that can be difficult to debug in the field. A number of automatic tools existing for checking code compliance again MISRA C and several high end compilers integrate support for checking MISRA C compliance, but they are all commercial and tend to be prohibitively expensive for hobbiest use. A PDF version of the MISRA C standard can be purchased for 10 British Pounds from MISRA Website, and is worth the investment if you want to develop safety critical or highly reliable systems.
JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS – (Alternatively: PDF File)
While this standard from Lockheed Martin Corporation is aimed at C++, there is a great deal of information that can be adopted for C development as well, and the document can be freely downloaded from numerous places on the web. They draw extensively on the MISRA standards mentionned above, but also offer a lot of general explanations and comments that can be a good reminder for both experience and beginning embedded developpers.
JPL Institutional Coding Standard for the C Programming Language
Published by the Jet Propulsion Laboratory at the California Institute of Technology, this C coding standard is also freely available on the web, and is more concise than the JSF Standard above, though it is also much higher-level and doesn’t go into nearly the same detail. It can be a good high-level overview of what key pitfalls to avoid and is worth reading through and making some notes in the margins when developping your own coding style. Some of the higher level recommendations to ensure code maintanability are:
- Rule 2 (routine checking): All code shall always be compiled with all compiler warnings enabled at the highest warning level available, with no errors or warnings resulting. All code shall further be verified with a JPL approved state-of-the-art static source code analyzer, with no errors or warnings resulting. [MISRA-C:2004 Rule 21.1]
- Rule 25: Functions should be no longer than 60 lines of text and define no more than 6 parameters. [Power of Ten Rule 4]
I agree that good standards are essential. Unit testing, as well as an independent test team (internal or external to the company) are great ways to catch more bugs.
Not sure how authoritative “IDesign” in terms of “C# coding standards”.
Example: It’s pretty rare to see the “m_” prefix for private members in C#. That’s a throwback to Win32 / MFC stuff, not .NET.
In terms of C# / .NET standards most would probably prefer “Framework Design Guidelines” (http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613/) and its associated MSDN content “Design Guidelines for Developing Class Libraries” (http://msdn.microsoft.com/en-us/library/ms229042.aspx).
Craig:
Most of the .Net developpers I know tend to follow the IDesign guidelines, but it’s hardly the only one … I haven’t done any serious .Net development in recent years myself, but it was the gold standard back then.
In any case … most C# code tends to be fairly consistently organised and formatted, perhaps because there is one authoritative source of information (and code samples) for .Net … unlike C compilers which are a dime a dozen and come from several different tool providers.
In any case … the important thing isn’t as much which standard as it is having a standard, however loose, to make collaborating and writing code a better experience for everyone involved.
Matt:
I really miss unit tests when doing embedded development (compared to working on the PC), but while there are a couple tools or platforms out there that can be adapted to work with embedded C they’re not nearly as fun or convenient as the tools that exist on other platforms.
Just looking at the JPL standards and it looks like they’re really restrictive. For example:
”
Rule 3 (loop bounds)
All loops shall have a statically determinable upper-bound on the maximum number of loop iterations
…
Rule 4 (recursion)
There shall be no direct or indirect use of recursive function calls.
…
Rule 5 (heap memory)
There shall be no use of dynamic memory allocation after task initialization.
”
This might be fine for a Jet Propulsion Lab, but in the real world to not have recursion or dynamic memory allocation is crippling.
I’m only looking at one standard and maybe the others a bit more forgiving…
It definately depends on what your writing SW for. Most of the C standards above are defined for safety critical systems (medical, automotive, etc.) are are far more restrictive that the large majority of OSHW projects. They’re provided as examples, but I’ve long thought it would be nice to see some better standards in C development for OSHW, such as defining a minimum number of steps that need to be respected. Inline documentation of methods (Doxygen or whatever else), max size of functions, etc.
There are a few people active in OSHW writing excellent, portable code (Akiba over at http://www.freaklabs.org is the best example I know of this), but it’s unfortunately less common than it should be and a lack of general community guidelines is probably part of the problem.
I think “Be picky only where it has been shown to matter.” is a good approach to coding standards. The following are worth looking
at:
Linux kernel coding style:
http://www.kernel.org/doc/Documentation/CodingStyle
FreeBSD’s style(9) man page:
http://www.freebsd.org/cgi/man.cgi?query=style&sektion=9
As far as coding standards, the secure coding FAQ at CERT is well worth a read:
http://www.cert.org/secure-coding/
I wasn’t aware of the CERT document … well written and worth a thorough read.