首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >宏定义中的Misra C错误

宏定义中的Misra C错误
EN

Stack Overflow用户
提问于 2013-12-09 18:50:27
回答 2查看 4.9K关注 0票数 3

这段代码报告了三个misra c错误:

  1. 不适当的宏观扩张
  2. 类函数宏定义
  3. 不带括号的宏参数

原来的守则是:

代码语言:javascript
复制
#define Wait(a, b)                         \
if (READ(b+0x1U))                          \
{                                          \
    while ((a & Write(b)))                 \
    {                                      \
        /* Do nothing - Busy wait */       \
    }                                      \
}

Here READ(b) is a macro and Write(b) is a function with no Misra C error.

我已经尝试更改它以删除错误。

代码语言:javascript
复制
#define Wait(a, b)                                                 \
if ((uint32_t)0U != READ((b)+0x1U))                                \
{                                                                  \
    while ((uint32_t)0U != ((uint32_t)(a) & Write((uint32_t)(b)))) \
    {                                                              \
        /* Do nothing - Busy wait */                               \
    }                                                              \
}

但我还是得到了前两个错误。需要做些什么来消除这些Misra C错误。

EN

回答 2

Stack Overflow用户

发布于 2013-12-10 12:37:51

1.不适当的宏观扩张

这是因为您没有正确地封装宏。若要解决此问题,必须将代码更改为:

代码语言:javascript
复制
#define Wait(a, b)                         \
                                           \
do {                                       \
  if (READ(b+0x1U))                        \
  {                                        \
    while ((a & Write(b)))                 \
    {                                      \
        /* Do nothing - Busy wait */       \
    }                                      \
  }                                        \
} while (0);

(当然,如果您的其余代码遵循MISRA并始终在每个ifforwhile语句之后使用while,则这是毫无意义的练习。)

2.类似功能的宏定义

您正在使用类似于函数的宏。这是米斯拉-C不允许的。将宏重写为函数。

然而,第19.7条规则是咨询性的,所以理论上你可以忽略它而不引起偏差。但在这种情况下,没有理由这样做。这没有理由需要是宏而不是函数。

3.没有括号的宏参数

正如您所猜测的,这与每个宏参数都是一个潜在的子表达式有关。假设有人将您的宏称为Wait(x+y, z)。您的代码会在遇到while循环时崩溃并烧毁,因为宏将扩展到while(x+y & Write(b))中,这与while(x + (y & Write(b)) )是一样的。

要解决这个问题,请使用括号包围ab的每个实例,如第二个示例所示。

这段代码报告了三个misra c错误:

你应该向Klockwork报告一个错误,他们的工具不能正常工作。它还应该检测到以下情况:

  • if (READ(b+0x1U))违反了规则13.2。符合MISRA的代码将是 如果(读(b+0x1U) != 0u)
  • while ((a & Write(b)))违反了规则13.2。符合MISRA的代码将是 ( (a &写(B))= 0u )

与米斯拉无关的关切事项:

  • (uint32_t)0U最好以0UL0ul的形式编写,它们是更易读的形式。
  • 坦率地说,这段代码一开始就很糟糕。试图使它符合现状,将把它变成一个完全不可读的混乱。代之以从头重写: 空等待(uint32_t a,uint32 b) { if(读取(b+ 0x1u) != 0u ) /*注释,在这里解释代码*/ {而( (a & while (B)) != 0u ) /*注释,在这里解释代码*/ {;/*什么都不做-繁忙的等待*}}
票数 6
EN

Stack Overflow用户

发布于 2013-12-09 19:24:54

有一个宏可以扩展到的列表,而if块不是其中之一。我相信这是因为它会对附加其他条款造成混乱。这里有更多关于这个的事。您可以使用这个构造:

代码语言:javascript
复制
#define MACRO(X)    \
do {                \
    body here       \
} while (0)

只要有可能,就应该使用函数而不是类似函数的宏。在不知道什么是READ的情况下,我不能说在这种情况下这是可能的。只有这样,才能摆脱这方面的警告。

第三个你已经知道了;你必须在ab周围加上括号。这里的想法是,如果宏中有类似于x*2的代码,并且有人将3+1作为x传递,那么如果没有括号,您将得到3+1*2,它是5,而不是(3+1)*2,后者几乎可以肯定是预期的。

关于您的代码,我要说的另一件事是,您确定需要&而不是&&

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20478315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档