Related functions, such as those that make up a library, should provide consistent and usable interfaces. Ralph Waldo Emerson said, "A foolish consistency is the hobgoblin of little minds," but inconsistencies in functional interfaces or behavior can lead to erroneous use, so we understand this to be a "wise consistency." One aspect of providing a consistent interface is to provide a consistent and usable error-checking mechanism. For more information, see API04-C. Provide a consistent and usable error-checking mechanism.
Noncompliant Code Example (Interface)
It is not necessary to go beyond the standard C library to find examples of inconsistent interfaces: the standard library is a fusion of multiple libraries with various styles and levels of rigor. For example, the
fputs() defined in the C Standard, subclause 126.96.36.199, is closely related to the
fprintf() defined in subclause 188.8.131.52. However,
fputs()'s file handle is at the end, and
fprintf()'s is at the beginning, as shown by their function declarations:
The argument order can be easily rearranged using macros; for example:
However, according to subclause 7.1.3 of the C Standard, the behavior of a program that defines a symbol, including a macro, with the same name as that of a standard library function, type, macro, or other reserved identifier is undefined.
Using inconsistent interfaces makes the code difficult to read, for example, by causing confusion when moving between code that follows this convention and code that does not. In effect, it becomes impossible to modify an interface once that interface has been broadly adopted. Consequently, it is important to get the interface design right the first time.
Compliant Solution (Interface)
The POSIX threads library [Butenhof 1997] defines an interface that is both consistent and fits in with established conventions from the rest of the POSIX library. For example, all initialization functions follow the same consistent pattern of the first argument being a pointer to the object to initialize with the subsequent arguments, if any, optionally providing additional attributes for the initialization:
Function arguments that refer to objects that are not modified are declared
const. Because the object pointed to by the first argument is modified by the function, it is not
const. For functions that implement a data abstraction, it is reasonable to define the handle for the data abstraction as the initial parameter. (See DCL12-C. Implement abstract data types using opaque types.) Finally, initialization functions that accept a pointer to an attribute object allow it to be
NULL as an indication that a reasonable default should be used.
Noncompliant Code Example (Behavior)
The shared folder and file copy functions in the VMware virtual infrastructure (VIX) API are inconsistent in the set of characters they allow in folder names. As a result, you can create a shared folder that you subsequently cannot use in a file copy function such as
Compliant Solution (Behavior)
Try to be consistent in the behavior of related functions that perform operations on common objects so that an object created or modified by one function can be successfully processed by a downstream invocation of a related function.
Failure to maintain consistency in interfaces and capabilities across functions can result in type errors in the program.
Key here (explains table format and definitions)
|ISO/IEC 9945:2003||Prior to 2018-01-12: CERT: Unspecified Relationship|
|ISO/IEC 23360-1:2006||Prior to 2018-01-12: CERT: Unspecified Relationship|
|ISO/IEC TR 24731-1||Prior to 2018-01-12: CERT: Unspecified Relationship|
|ISO/IEC TR 24731-2||Prior to 2018-01-12: CERT: Unspecified Relationship|
|MISRA C:2012||Rule 21.3 (required)||Prior to 2018-01-12: CERT: Unspecified Relationship|
|MISRA C:2012||Directive 4.12 (required)||Prior to 2018-01-12: CERT: Unspecified Relationship|
|[Seacord 2013]||Chapter 2, "Strings"|
|[VMware 2007]||VIX API Version 1.1.1 (for Workstation 6.0.1) Release Notes|