如何声明带有易失性元素的静态数组?

时间:2018-06-27 09:45:00

标签: c arrays volatile

所用术语的澄清:

对于静态数组,我的意思是数组静态分配的内存如下:int x [10]。

问题

我需要声明一个带有易失性元素的静态数组。 如果我很好地理解了挥发性限定词的工作原理,应该是:

volatile uint8_t *x; // x is a pointer to volatile uint8_t
uint8_t *volatile x; // x is a volatile pointer to uint8_t
volatile uint8_t *volatile x; // x is a volatile pointer to volatile uint8_t 

好,但是现在我需要对静态数组做同样的事情。 我尝试过:

volatile uint8_t x[10];  // Only the pointer is decleared as volatile
uint8_t volatile x[10];  // Same as above
volatile uint8_t *x3[10]; // Casting problems and errors when I do ...  
*x3[0] = 1; // ... something like this. Moreover, I do not know if this...
            // ... statement declares the uint8_t element as volatile

谢谢!

更新

好的,正如我应该使用的注释中突出显示的那样:

volatile uint8_t x[10]

据我了解,问题不在于声明,而在于代码中此变量的用法。我将此元素传递给原型为的函数:

static void functionName(uint8_t *buffer, uint32_t size);

我以这种方式调用该函数:

functionName(x, 10);

编译器报告:传递'functionName'的参数1会从指针目标类型中丢弃'volatile'限定符

我无法更改函数原型,如何解决该问题?

2 个答案:

答案 0 :(得分:1)

声明一个由uint8_t类型的10个volatile元素组成的静态数组所要做的只是:

volatile uint8_t x[10];

请注意,这是一个数组的声明,在此步骤中,与指针无关。

注意:在您的代码后面,如果您使用x,它可能会衰减为指向第一个volatile元素的指针,但是在这种情况下,该指针将具有一个常量值,该值在链接处给出步。指示值显然是易变的。

答案 1 :(得分:0)

今天我自己偶然发现了这个问题。 变量有时可能是易失的。 易失性意味着它的值可以在程序流程之外更改。通过并行线程或ISR。 现在,如果ISR是“意外地”更改值的东西,则它在ISR本身内部不会发生意外更改。因此,对于ISR,该变量不是可变的,并且禁用编译器优化会适得其反。 如果我从ISR内部(仅从那里)调用一个函数,则该变量不是volatile,并且我不想传递指向volatile的指针,因为这样会产生效率低下的代码。

对于这种情况,我发现的解决方案是有两个声明:

int a[x] = {};
volatile int * b = a;

现在,外界使用b(在头文件中全局声明)并将b指向的值视为volatile,而ISR(在本地)同时定义这两者并使用a,将这些值视为非易失性。

嗯,这是一个非常特殊的情况。通常,函数仅看到函数参数声明。这是可变的还是非可变的,因此功能将始终将参数视为可变或非可变。它不能根据传递的参数的原始volatile限定符状态在两个可能完全不同编译的代码块之间自动切换。因此,警告。