在 C 中正确丢弃 volatile 变量内容的替代方法是什么?

What would be an alternate way to properly discard a volatile variable content in C?

在对微控制器进行编程时,有时需要读取寄存器以重置某些标志。这些寄存器是内存映射的,并在代码中声明为指向 volatile 的指针。

以下一个片段为例:

typedef volatile struct _Ifx_SCU
{
   ...
   uint32_t reg;
   ...
}Ifx_SCU;


#define MODULE_SCU ((*(Ifx_SCU*)0xF0036000u))


void foo(void)
{
   ... 

   MODULE_SCU.reg; /* Read required to reset bits in reg */

   ...
}

这里必须读取 reg 才能重置它的位,除了读取它们之外没有其他方法可以重置某些位,因此,MISRA 规则检查器抱怨说有死代码,没错

我的问题是 读取和丢弃 **reg 值以避免 "dead code" 的替代方法是什么?** 因为使用方法post Casting the results of a volatile expression to void 情况非常相似,我仍然违反了 MISRA c 2012 规则。我无法更改 #define MODULE_SCU 或结构中的任何内容,因此正确的替代方法是正确的方法。

当我从这个线程中读取时,我不想让编译器强制转换为 void:What does void casting do? 因为如果我强制转换为 void,那么优化器可能会优化读取,这是不可取的。

不要太在意代码片段的正确性,我只是把它包含在说明问题中

Here reg has to be read in order to reset it's bits, there is no other way to reset some bits other thatn reading them, So, MISRA rule checker is complaining that there is dead code and it's right.

死代码是什么都不做的代码。从技术上讲,死代码是一种没有副作用的语句。在这种情况下,volatile 关键字表明它确实在做某事,它正在读取内存并因此重置位,这是一个明确的副作用。

volatile 关键字还确保兼容的优化器不会删除该行。

所以,事实上 MISRA 规则检查器是错误的,代码是完美的,不应该被标记。

没有必要找到正确方法的替代方法。

读取对象并丢弃结果的正确方法是:

(void)object;

转换实际上不是必需的,但可能会阻止编译器抱怨(实际上不确定 MISRA)。仅供参考:这是一个 expression-statement.

如果 object 是合格的 volatile,访问可能不会被编译器优化掉,因为这个关键字告诉编译器有副作用,即使编译器没有看见。强制转换适用于表达式的结果("read"),而不是对象,因此它 而不是 如您的评论所暗示的那样删除限定符。

MISRA 检查器不应该抱怨,因为该行实际上 做了 一些事情。 (这由 volatile 限定符 暗示)。如果该工具无论如何都会抱怨,请将其丢弃。更何况这不是你第一次遇到麻烦了。