宏定义中的Misra C错误

Rog*_*ews 3 c macros misra

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

  1. 不恰当的宏观扩张
  2. 类似函数的宏定义
  3. 没有括号的宏参数

原始代码是:

#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.
Run Code Online (Sandbox Code Playgroud)

我试图更改它以消除错误

#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 */                               \
    }                                                              \
}
Run Code Online (Sandbox Code Playgroud)

但我仍然得到前两个错误.需要做些什么来消除这些Misra C错误.

Lun*_*din 6

1.不适当的宏观扩张

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

#define Wait(a, b)                         \
                                           \
do {                                       \
  if (READ(b+0x1U))                        \
  {                                        \
    while ((a & Write(b)))                 \
    {                                      \
        /* Do nothing - Busy wait */       \
    }                                      \
  }                                        \
} while (0);
Run Code Online (Sandbox Code Playgroud)

(当然,这是毫无意义的运动,如果你的代码的其余部分遵循MISRA-C和始终使用{}后,每if,forwhile陈述.)


2.功能类宏定义

您正在使用类似函数的宏.MISRA-C不允许这样做.将宏重写为函数.

但是,规则19.7是建议性的,所以你理论上可以忽略它而不会产生偏差.但在这种情况下没有理由这样做.没有理由认为这需要是一个宏而不是一个函数.


3.Macro参数没有括号

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

为了解决这个问题,围绕的每个实例a,并b用括号,如你的第二个例子.


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

您应该向Klockwork报告错误,他们的工具无法正常工作.它还应该检测到以下内容:


非MISRA相关问题:

  • (uint32_t)0U应该优选地写成0UL或者0ul更可读的形式.
  • 坦率地说,这段代码很难开头.试图使其符合MISRA标准,将其变成一个完全不可读的混乱.改为从头开始改写:

    void Wait (uint32_t a, uint32 b)
    {
      if( READ(b + 0x1u) != 0u )           /* comment here, explaining the code */
      {
        while ( (a & Write(b)) != 0u )     /* comment here, explaining the code */
        {
          ;                                /* Do nothing - busy wait */
        }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)