const volatile指针函数参数

时间:2012-12-07 12:21:19

标签: c const volatile

对于嵌入式SW项目,我们需要使用一些const volatile TYPE *指针。现在我们有一些计算函数,如下所示:

uint8 calc(const volatile uint8 *array, uint8 value) { ... }

在功能执行期间,两个变量的数据都没有变化。

调用代码如下所示:

const volatile uint8 *array = (const volatile uint8 *)0x00010111;
uint8 value = 8;

uint8 result = calc(array, value);

现在的问题是,如果我们设计没有volatile参数的calucation函数会有区别:

uint8 calc(const uint8 *array, uint8 value) { ... }

对于这个电话,我们抛弃了volatile:

uint8 result = calc((const uint8 *)array, value);

第二种解决方案的优点是更灵活:我们也可以将该函数用于非易失性变量。但它是否有所作为,如果我们抛弃volatile并且我们的编译器做了一些强有力的优化?

3 个答案:

答案 0 :(得分:3)

您可以始终将该函数与非易失性参数一起使用。它只是函数中的代码处理给定的对象,就像它们是易失性的一样(最有可能在路上失去性能)。有点难以想象具有易失性参数的函数(“因为它们可能会在没有通知的情况下发生变化”)可以明智地做到。在您编写时,在您的情况下数据不会发生任何变化,因此最灵活的解决方案是声明参数const并忘记volatile。

请相当,请使用“uint8_t”而不是像uint8这样的本土类型名称 - 自1996年以来它就是标准!

答案 1 :(得分:1)

有两种情况:函数是直接操作硬件寄存器等。然后你必须在参数中有volatile。或者该功能与硬件寄存器完全无关。然后它不应该有volatile。这两种情况之间没有中间立场。

此外,calc((const uint8_t*)array, value);只是一个糟糕的,可能是错误的

版本
const uint8_t* ptr = array;
calc(ptr, value);

前一种形式很糟糕,因为函数参数的评估顺序是未指定的行为。编译器可能首先选择评估左操作数或右操作数,并且您无法知道或承担订单。由于访问volatile是一种副作用,因此每次构建程序时,原始代码都可以提供不同的结果。这在实时嵌入式系统中尤其成问题(并且可能是危险的)。

因此,建议不要在表达式中访问volatile变量(参见MISRA-C:2004 12.2)。

答案 2 :(得分:0)

这取决于volatile - ness。

会发生什么

如果在执行函数期间此数组中的值发生更改并且应注意这些更改,请将它们设为volatile

如果无关紧要,或者“旧”值更重要,请省略volatile