Creating a Set of Guidelines
Coding guidelines should not be written in isolation (that is, by considering only their individual technical merits). The factors involved in how a set of guidelines might be used in various software development environments also need to be considered. For example, these factors might include the following:
- How adherence to each recommendation might be checked
- Management acceptance of the recommendations made; for example, the cost of enforcement shouldn’t be excessive
- How a set of guidelines fit together as a package; for instance, the set shouldn’t be so restrictive that it’s impossible to write any software without violating one of the guidelines
There are an infinite number of possible coding guidelines. To guarantee that all possible program faults are covered, an infinite set of guidelines would be required. In practice, however, most coding guideline documents contain around 100 recommendations. In some sense, the recommendations that survive to become part of a coding guideline document might be considered to be the most important recommendations, with importance possibly being measured in one of several ways:
- Maximizing the number of faults prevented
- Having the most support from the authors of the document (which isn’t always based on any evidence that the guideline will prevent a significant number of faults occurring)
- Marketing potential (by meeting user expectations in terms of what developers believe should be included in such a document)
While the underlying reasons for the mistakes made by developers—such as the use of uninitialized variables—might apply to all computer languages, most coding guideline documents are written to deal with specific languages.
Traditionally, the main source of guideline recommendations has been practical experience; that is, those language constructs that keep appearing as the root causes of faults (sometimes known as common mode failures). While past experience of faults is still a major source of guideline recommendations, the underlying reasons for why developers make the mistakes that lead to these faults are slowly being discovered. In one form or another, these mistakes are all the result of human fallibility.
While cognitive psychology (the study of mental processes) is still in its infancy, the models researchers have created of the various components used during reading and comprehension—for example, visual processing of text, short-term memory, and so on—do provide some insight into the processes involved in reading and writing code.
Two cognitive-based root causes of mistakes are developer knowledge failures (for example, where developers don’t realize they have insufficient knowledge) and developer performance failures (such as calculating an incorrect answer to a problem). An example of a physical root cause of mistakes is mistyping. This can become a fault if it goes undetected, as when the mistyped characters didn’t prevent the source being successfully compiled.
Possible solutions to knowledge-based mistakes include reducing the amount of information that developers need to know, or organizing the information contained in source code in such a way that there are fewer demands on developers to correctly recall or recognize information. This information might relate to the details of programming language semantics, the behavior of compilers, or knowledge about the source code used to implement an application.
Some coding guidelines recommend against the use of constructs that are obvious faults (for example, "Don’t read the value of an uninitialized variable"). To understand the reason for this kind of guideline, it’s necessary to understand the approach that many managers take toward checking for faults in their developers’ code: If it isn’t in the guidelines document, there’s no need to check for it. While high-quality static analysis tools can perform many more checks than are required by the various coding guideline documents, this minimalist checking mentality—in other words, lowest cost to that manager—means that developers may only be allocated the time needed to run analysis tools with certain specific guideline checks enabled. Yes, it’s obvious to all developers that some guidelines are simply recommending against obvious faults. Including them in the document means that managers are more likely to allocate resources for developers to check for and correct any violations.
The approach taken by the authors of MISRA-C was to base most of their guidelines on constructs whose behavior, in one form or another, was not uniquely specified by the language standard—a different compiler, or even the same compiler in different contexts, could generate machine code that behaved differently for the same language construct—on the basis that developers might write code that depends on a specific behavior. Other MISRA-C guidelines were based on avoiding known bugs in compilers and constructs that experience had shown to be a common cause of developer error.