Misra-C 与 X-macros 兼容吗?

Is Misra-C compatible with X-macros?

可以说在许多情况下 X-macros 增加了安全性,因为它更容易确保生成的数组长度相同。


然而,Misra C(来自 2004 年参考)规则似乎有很多限制使用的预处理器规则:

Rule 19.1 (advisory) #include statements in a file should only be preceded by other preprocessor directives or comments.

如果源 table 在其他文件中,例如生成数组,就会很麻烦。但这是建议性规则,因此可以解决。

Rule 19.4 (required) C macros shall only expand to a braced initializer, a constant, a string literal, a parenthesized expression, a type qualifier, a storage class specifier, or a do-while-zero construct.

应该不是问题,因为大多数 X 宏用于生成数组初始值设定项或常量。

Rule 19.6 (required) #undef shall not be used.

使一些 X-macro 的使用模式成为不可能。不幸的是,但并没有完全阻止 X-macros。

Rule 19.7 (advisory) A function should be used in preference to a function-like macro.

仅建议规则。

Rule 19.12 (required) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro definition.

可以使用嵌套宏解决。

Rule 19.13 (advisory) The # and ## preprocessor operators should not be used.

例如在生成枚举时很麻烦,但这只是建议规则。

Rule 19.15 (required) Precautions shall be taken in order to prevent the contents of a header file being included twice.

在某些情况下会很麻烦,但可以解决。


看上面的内容,如果你小心的话,似乎可以将 X-macros 与 Misra C 代码一起使用。

我的结论是正确的,还是我遗漏了一些规则?

在我看来,使用 X-macros 来增加类型安全是一个相当薄弱的论据。他们所做的主要事情是简化维护并消除代码重复问题。但就像任何类似函数的宏一样,当一切都失败时,它们是最后的手段。

确保数组长度正确等的正确方法是使用 static_assert(或某些 hack:ish pre-C11 机制),这会产生编译时错误。

一次解决您的问题:

  • include statements in a file should only be preceded by other preprocessor directives or comments. ... Troublesome if source table is in other file which is included...

    这是一条合理的规则,没有理由偏离它。如果您在 #include 的另一个文件中有源 table,那么问题是什么?规则没有提到预处理的头文件。

    这条规则的主要原因是为了防止人们在文件中间的某个地方扔进 #include。 (这很可能是由一些遗留的调试代码引起的。)

  • Rule 19.4 (required) C macros shall only expand to a braced initializer, a constant, a string literal, a parenthesized expression, a type qualifier, a storage class specifier, or a do-while-zero construct.

    如果解释为(递归)展开的宏,那应该不是问题,因为 X 宏最终应该归结为常量、类型等。规则说 "expand" 所以我认为它指的是完全展开的宏。

    此规则已在 MISRA-C:2012 中完全删除并替换为其他更具体的规则,例如不使用与语言关键字同名的宏等。

  • Rule 19.6 (required) #undef shall not be used.

    此规则已在 MISRA-C:2012 中放宽,从要求变为建议。反对该规则的一个有效论据确实是 #undef 对于 X-macros 是必要的,但我不能说这是否是它被放宽的原因。

    大多数情况下,规则是为了防止像 #undef NULL 这样的代码或某些人可能会得到的其他奇怪和晦涩的想法。

  • Rule 19.7 (advisory) A function should be used in preference to a function-like macro.

    一般来说,MISRA-C反对使用类函数宏,这在MISRA-C:2004和当前的MISRA-C:2012中都是建议性规则。并且有很好的理由:我们都知道类函数宏通常是邪恶的,但我们也知道它们通常是必要的邪恶。

  • Rule 19.12 (required) There shall be at most one occurrence of the # or ## preprocessor operators in a single macro definition.

    此规则已在 MISRA-C:2012 中放宽为咨询。如果没有这两个,可能很难编写一些 X 宏。它们有一些有效的危险,但其他规则已经解决了。我发现与 MISRA-C:2012 中的 X 宏没有冲突。

  • Rule 19.15 (required) Precautions shall be taken in order to prevent the contents of a header file being included twice.

    强制使用头部保护的合理规则。应该没有理由偏离它,有或没有 X 宏。

结论:
之前的MISRA-C:2004不能使用X宏,现在的MISRA-C:2012可以使用。我强烈建议升级,因为 MISRA-C:2012 是一个更好的重大变化。各种迂腐的规则已被删除、放宽或重写。复杂的规则,如关于隐式类型提升的规则,已得到显着改进。现在有 C99 支持。等等。

我自己在 MISRA-C:2012 中使用了 X-macros,据我所知,不需要偏离任何必需的规则。

请记住,MISRA-C:2004 是一套指南......它甚至为您提供了一个流程,以防您想要执行指南中禁止的操作。

Looking at the above, it seems that it is possible to use X-macros with Misra C code, if you are careful.

是的...您可以提出偏差 - 这需要您了解您决定违反指南的后果,证明违规行为的合理性,并获得适当的批准。

在这种情况下,偏离。