无法访问参数

Ash*_*101 1 c operating-system pointers volatile coverity

我正在调试一段代码,我遇到了一个错误,我似乎无法找到解决方案,它与副作用错误有关,因为变量被声明为 volatile。错误在一行中:

DBG_SLOTS(TIMER_VAR_NAME.maximumS == randomNUM);
Run Code Online (Sandbox Code Playgroud)

错误:_AssertImpl() 的参数 timerVar 有副作用,因为该变量是易失性的。包含函数在构建中的工作方式可能不同。

下面给出了最小的可重现代码:



typedef volatile struct
{
   uint32_t          maximumS;        // Maximum soft timer
   callbackEntry_t   callbackTable[ CALLBACK_NUM_MAX ];
} regression_t

#if (defined(ROM) || defined(RAM) || defined(DLE) || defined(BLLNK))
   timerVar_t TIMER_VAR_NAME;
#endif

uint32_t TServ_MaxInUse;

BackNum_t SEC SYS_Calls(uint64_t calls, PVFV_t callb, BOOL periodic)
{
   int runtimeTick = 0;
   TimeCallBackNum_t callbackNum;
   uint32_t intPosture;
     // ++++

  G_SLOTS(TIMER_VAR_NAME.maximumS == TServ_MaxInUse);
........
}
Run Code Online (Sandbox Code Playgroud)

Sco*_*eak 5

在 C(和 C++)中,访问volatile对象是一种可能有副作用的操作。引用 C99 6.7.3/6:

具有 volatile 限定类型的对象可能会以实现未知的方式进行修改,或者具有其他未知的副作用。

Coverity 警告您该断言的表达式访问一个volatile对象,因此如果断言被禁用,这样做的可能副作用将不会发生,从而使您的调试和生产版本的行为不同。

解决此问题的一种方法是首先将值读入非volatile局部变量。也就是说,而不是:

DBG_TIMER_SERVICES_ASSERT_MAX_SLOTS(TIMER_VAR_NAME.maximumS == debugTimerServices_MaxSlotInUse);
Run Code Online (Sandbox Code Playgroud)

你可以写:

uint32_t tmp = TIMER_VAR_NAME.maximumS;
DBG_TIMER_SERVICES_ASSERT_MAX_SLOTS(tmp == debugTimerServices_MaxSlotInUse);
Run Code Online (Sandbox Code Playgroud)

这样,无论断言是否启用,副作用(如果有)都会发生。

也就是说,根据代码中的名称,很明显这里没有副作用(volatile仅用于确保编译器了解该值自发变化),所以我可能只是在 Coverity GUI 中标记它作为误报或故意并继续。