MISRA Discussion Forums

Full Version: Rules 21.1 and 21.2. Possible contradiction with rule 11.9 and directive 4.6.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Good day. I'm analyzing a few findings reported by a static analysis tool for a project that per project guidelines disallows any use of standard libraries. This maximizes control over the code and makes all the project code subject to MISRA C compliance. To comply with MISRA C:2012 and to avoid possible clashes with unit testing frameworks that do make use of standard libraries the internal standard-like macros and functions (like "offsetof" and "memcpy") have customized names.

Problems arise when trying to adhere to the rule 11.9 by defining the macro "NULL" and to the directive 4.6 by defining the exact-width integer types. These rules prescribe the use of standard names while the rules 21.1 and 21.2 prohibit such definitions. The project employs static assertions to guarantee that all the standard properties of the exact-width integer types and other integer types (like "size_t" and "ptrdiff_t") hold true for whatever (32-bit or 64-bit) target the project is compiled. The project is C99-specific, and I assume the MISRA C Working Group would rightfully point out that the directive 4.6 recommends inclusion of "stdint.h" in this case and therefore does not strictly contradict the rule 21.2 due to the standard headers being out of the MISRA C compliance scope. In any case the rationale of the rule 21.2 does not seem to apply here, as the typedef-names have no linkage and are therefore not reserved as per "C99. 7.1.3 Reserved identifiers" as long as no associated header is included.

My questions are:
1) How can the contradiction between the rules 11.9 and 21.1 be resolved with respect to the macro "NULL" in the context of the given project?
2) How can the contradiction between the directive 4.6 and the rule 21.2 be resolved with respect to the exact-width integer types in the context of the given project?
3) Rule 21.1 acknowledges that defining identifiers being subject to the question 2 "is well-defined provided that the header is not included", but still prohibits such definitions to avoid confusion. Does this prohibition also apply for the rule 21.2? What exactly causes confusion provided all the properties guaranteed by the standard are also ensured for the definitions made outside of the standard headers?

Kind regards
Question 1.
Rule 11.9 permits both the use of "(void*)0" or the use of a macro that expands to "(void*)0".
The examples in the MISRA C:2012 guidelines includes the compliant use of
#define MY_NULL_2 (void*)0

Question 2.
The amplification of rule 21.1 ( which is also applied to rule 21.2 ) refers to "identifiers in file scope described in Section 7, "Library", of The Standard". There is no mention of linkage and therefore "reserved identifiers" also covers typedef names declared in stdint.h.

Ideally for C99 the types provided by stdint.h should be used. The project plan should otherwise provide documentation as to why this aspect of directive 4.6 is not followed.
The other aspects of directive 4.6 can be followed by using typedefs which do not clash with names in stdint.h. This avoids a violation of rule 21.1. For example:
typedef int INT32;

Question 3.
Yes, the prohibition also applies to rule 21.2. The whole of the amplification for 21.1 applies to 21.2.
The rule applies even if the standard header file is not included. Confusion might arise if reviewers or later developers make an incorrect assumption that the behaviour of the declaration behaves in the same way as that of the standard library.

Rule 21.2 may be deviated if the project can guarantee that the behaviour is the same as that of the standard library. The evidence for a deviation to rule 21.2 should be recorded in a //deviation record//. You are advised to read the MISRA Compliance document which can be found at https://tinyurl.com/MisraCompliance [^] which gives advice on writing //deviation records//.