对于静态数组,我的意思是数组静态分配的内存如下: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'限定符
我无法更改函数原型,如何解决该问题?
答案 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限定符状态在两个可能完全不同编译的代码块之间自动切换。因此,警告。