简体   繁体   English

const volatile指针函数参数

[英]const volatile pointer function argument

For a embedded SW project we need to use some const volatile TYPE * pointers. 对于嵌入式SW项目,我们需要使用一些const volatile TYPE *指针。 Now we have some calculation functions which are looking like following: 现在我们有一些计算函数,如下所示:

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

The data of both variables is not changing during the function execution. 在函数执行期间,两个变量的数据都不会改变。

The calling code looks like following: 调用代码如下所示:

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

uint8 result = calc(array, value);

The question is now, would be there a difference, if we design the calucation functions without volatile arguments: 现在的问题是,如果我们设计没有volatile参数的calucation函数会有区别:

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

For the call we cast away the volatile: 对于电话,我们抛弃了波动:

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

Pros for the second solution are more flexibility: We can use the function also for non volatile variables. 第二种解决方案的优点是更灵活:我们也可以将该函数用于非易失性变量。 But does it make a difference, if we cast away the volatile and our compiler does some strong optimizations? 但它是否有所作为,如果我们抛弃volatile并且我们的编译器做了一些强有力的优化?

You can ALWAYS use the function with non-volatile arguments. 您始终可以将该函数与非易失性参数一起使用。 Its just that the code in the function handles the given objects as if they were volatile (losing performance on the way, most likely). 它只是函数中的代码处理给定的对象,就像它们是易失性的一样(最有可能在路上失去性能)。 Its a bit hard to imagine what a function with volatile arguments ("because they might change without notice") could sensibly do. 有点难以想象具有易失性参数的函数(“因为它们可能会在没有通知的情况下发生变化”)可以明智地做到。 As you write, in your case the data doesn't change anyway, so the most flexible solution is to declare the parameters const and forget about volatile. 在您编写时,在您的情况下数据不会发生任何变化,因此最灵活的解决方案是声明参数const并忘记volatile。

And pretty please, use "uint8_t" and not some homegrown type name like uint8 - its in the standard since 1996! 请相信,请使用“uint8_t”而不是像uint8这样的本土类型名称 - 自1996年以来它就是标准!

There are two cases: either the function is manipulating hardware registers etc directly. 有两种情况:功能是直接操作硬件寄存器等。 Then you must have volatile in the parameter. 然后你必须在参数中有volatile。 Or the function has nothing to do with hardware registers at all. 或者该功能与硬件寄存器完全无关。 Then it should not have volatile. 然后它不应该有波动。 There is no middle ground between those two cases. 这两个案件之间没有中间立场。

Furthermore, calc((const uint8_t*)array, value); 此外, calc((const uint8_t*)array, value); is just a bad, possibly buggy version of 只是一个糟糕的,可能是错误的版本

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

The former form is bad, because the order of evaluation of function arguments is unspecified behavior. 前一种形式很糟糕,因为函数参数的评估顺序是未指定的行为。 The compiler may chose to evaluate the left operand or the right operand first, and you cannot know or assume the order. 编译器可能首先选择评估左操作数或右操作数,并且您无法知道或承担订单。 Since accessing a volatile is a side-effect, your original code can give different results each time the program is built. 由于访问volatile是一种副作用,因此每次构建程序时,原始代码都可以提供不同的结果。 This is especially problematic (and possibly dangerous) in real time embedded systems. 这在实时嵌入式系统中尤其成问题(并且可能是危险的)。

Therefore it is recommended practice to never access volatile variables inside expressions (see MISRA-C:2004 12.2). 因此,建议不要访问表达式中的volatile变量(参见MISRA-C:2004 12.2)。

That depends on what really can happen due to volatile -ness. 这取决于由于volatile而真正发生的事情。

If the values in this array change during function execution and these changes should be noticed, let them be volatile . 如果在执行函数期间此数组中的值发生更改并且应注意这些更改,请将它们设置为volatile

If it doesn't matter, or if the "old" values are more important, omit the volatile . 如果无关紧要,或者“旧”值更重要,请省略volatile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM