【问题标题】:Is Misra-C compatible with X-macros?Misra-C 与 X 宏兼容吗?
【发布时间】:2018-09-27 08:01:57
【问题描述】:

可以说,在许多情况下,X 宏可以提高安全性,因为它可以更轻松地确保生成的数组具有相同的长度。


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

规则 19.1(建议)文件中的#include 语句只能在其他预处理器指令之前 或 cmets。

如果源表在其他文件中,例如生成数组,则会出现问题。但这是建议性规则,因此可以解决。

规则 19.4(必需)C 宏只能扩展为花括号初始值设定项、常量、字符串文字、 带括号的表达式、类型限定符、存储类说明符或 do-while-zero 构造。

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

规则 19.6(必需)#undef 不得使用。

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

规则 19.7(建议)应优先使用函数而不是类似函数的宏。

仅限咨询规则。

规则 19.12(必需)在单个预处理器中最多出现一次 # 或 ## 预处理器运算符 宏定义。

可以使用嵌套宏来解决。

规则 19.13(建议)不应使用 # 和 ## 预处理器运算符。

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

Rule 19.15 (required) 应采取预防措施以防止包含头文件的内容 两次。

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


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

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

【问题讨论】:

  • 19.4 的意思是立即展开还是通过另一个宏展开也可以接受?那可能不是首发。
  • @StoryTeller 好点。我以为它列出了所有预处理后的最终结果,但我不确定。

标签: c misra x-macros


【解决方案1】:

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

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

一次解决一个问题:

  • 文件中的包含语句只能在其他预处理器指令或 cmets 之前。 ... 如果源表在包含的其他文件中,则很麻烦...

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

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

  • 规则 19.4(必需)C 宏只能扩展为花括号初始值设定项、常量、字符串文字、带括号的表达式、类型限定符、存储类说明符或 do-while-zero 构造。

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

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

  • 规则 19.6(必需)#undef 不得使用。

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

    大部分规则是为了防止像#undef NULL 这样的代码或其他一些人可能会得到的奇怪和晦涩的想法。

  • 规则 19.7(建议)应优先使用函数而不是类似函数的宏。

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

  • 规则 19.12(必需)在单个宏定义中最多应出现一次 # 或 ## 预处理器运算符。

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

  • 规则 19.15(必需)应采取预防措施,以防止头文件的内容被包含两次。

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

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

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

【讨论】:

  • 重新访问这个...#define LIST_OF_STUFF(X) \ X(...) 形式的 X 宏使用 LIST_OF_STUFF(SOME_MACRO) 而不是 LIST_OF_STUFF(X) 调用。这意味着我们不必一直重新定义这个神奇的“X”。代码变得更加灵活,我们不需要使用#undef
【解决方案2】:

请记住,MISRA-C:2004 是一套指南……它甚至为您提供了一个流程,以防您想做一些指南规定不要做的事情。

看上面,好像可以用X-macros 如果您小心的话,请使用 Misra C 代码。

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

在这种情况下,偏离。

【讨论】:

  • 根据我的回答,我的结论是不需要任何偏差,因为“X-macros”只会违反咨询规则。这假设 MISRA-C:2012,它允许 #undef
猜你喜欢
  • 1970-01-01
  • 2020-02-23
  • 2019-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-02
  • 2021-05-14
相关资源
最近更新 更多